代码之家  ›  专栏  ›  技术社区  ›  William Wong

查找列表的所有组合的交集

  •  0
  • William Wong  · 技术社区  · 2 年前

    我的最终目标是在 R 。然而,我的数据很大,并且不是以可用于直接输入的方式存储的,我有:

    1. 4组(它们将是冲积地块的轴线)
    2. 在这些组中的每一个中,都包含一个矢量列表

    我的想法是使用 length(intersect()) 以获得向量列表的每个组合的频率。

    为了获得列表的组合,我使用 cross() 来自 purrr 。我不确定这是否是获得这个组合矩阵的正确方法,我对其他方法持开放态度。同样,我对能够实现这一目标的其他渠道持开放态度。主要原因是我被困在这一点上,找不到一个好的方法来找到向量列表的交集。

    下面是一个玩具数据集和我想要获得的预期输出(我手动键入结果):

    library(tidyverse)
    group1 <- list(module1 = c("test1", "test2", "test3", "test4", "test5", "test6"),
                   module2 = c("test7", "test8", "test9", "test10"),
                   module3 = c("test11", "test12", "test13"))
    
    group2 <- list(module1 = c("test3", "test4", "test5", "test7", "test8"),
                   module2 = c("test1", "test12", "test13"),
                   module3 = c("test2", "test6", "test11"))
    
    group3 <- list(module1 = c("test3", "test5", "test6", "test8"),
                   module2 = c("test1", "test7", "test9", "test10"),
                   module3 = c("test13", "test14", "test15"))
    
    list_combination <- list(group1 = names(group1), group2 = names(group2), group3 = names(group3)) %>% 
      cross() %>% 
      bind_rows()
    
    expected_result_intersect <- list_combination %>%  #below are the results
      mutate(intersect_result = list(
        c("test3", "test5"), #intersect(group1_module1, intersect(group2_module1, group3_module1))
        c("test8"), #intersect(group1_module2, intersect(group2_module1, group3_module1))
        NULL, #intersect(group1_module3, intersect(group2_module1, group3_module1))
        NULL, #intersect(group1_module1, intersect(group2_module2, group3_module1))
        NULL, #intersect(group1_module2, intersect(group2_module2, group3_module1))
        NULL, #intersect(group1_module3, intersect(group2_module3, group3_module1))
        c("test6"), #intersect(group1_module1, intersect(group2_module3, group3_module1))
        NULL, #intersect(group1_module2, intersect(group2_module3, group3_module1))
        NULL, #intersect(group1_module3, intersect(group2_module3, group3_module1))
        c("test5"), #intersect(group1_module1, intersect(group2_module1, group3_module2))
        c("test7"), #intersect(group1_module2, intersect(group2_module1, group3_module2))
        NULL, #intersect(group1_module3, intersect(group2_module1, group3_module2))
        c("test1"), #intersect(group1_module1, intersect(group2_module2, group3_module2))
        NULL, #intersect(group1_module2, intersect(group2_module2, group3_module2))
        NULL, #intersect(group1_module3, intersect(group2_module2, group3_module2))
        NULL, #intersect(group1_module1, intersect(group2_module3, group3_module2))
        NULL, #intersect(group1_module2, intersect(group2_module3, group3_module2))
        NULL, #intersect(group1_module3, intersect(group2_module3, group3_module2))
        NULL, #intersect(group1_module1, intersect(group2_module1, group3_module3))
        NULL, #intersect(group1_module2, intersect(group2_module1, group3_module3))
        NULL, #intersect(group1_module3, intersect(group2_module1, group3_module3))
        NULL, #intersect(group1_module1, intersect(group2_module2, group3_module3))
        NULL, #intersect(group1_module2, intersect(group2_module2, group3_module3))
        c("test13"), #intersect(group1_module3, intersect(group2_module2, group3_module3))
        NULL, #intersect(group1_module1, intersect(group2_module3, group3_module3))
        NULL, #intersect(group1_module2, intersect(group2_module3, group3_module3))
        NULL #intersect(group1_module3, intersect(group2_module3, group3_module3))
        ))
    
    expected_result_counts <- expected_result_intersect %>% 
      rowwise() %>% 
      mutate(Freq = length(intersect_result))
    
    
    library(ggalluvial)
    ggplot(expected_result_counts,
           aes(y = Freq, axis1 = group1, axis2 = group2)) +
      geom_alluvium(aes(fill = group3), width = 1/12) +
      geom_stratum(width = 1/12, fill = "black", color = "grey") +
      geom_label(stat = "stratum", aes(label = after_stat(stratum))) +
      scale_x_discrete(limits = c("Group1", "Group2"), expand = c(.05, .05)) +
      scale_fill_brewer(type = "qual", palette = "Set1") +
      ggtitle("test plot")
    

    需要注意的事项:

    • 我不想在小组内进行任何组合,也就是说,我想 不需要 intersect(group1_module1, group1_module2) 作为角色 组内的矢量具有不同的元素。
    • 在真实的数据集中,我每组有50多个模块。因此,如果所提出的方法是计算/RAM有效的,那就太好了。

    我对其他语言处理数据持开放态度,但更喜欢使用R来绘制图形,因为我更熟悉 ggplot .

    谢谢

    1 回复  |  直到 2 年前
        1
  •  2
  •   Onyambu    2 年前
    map(cross(lst(group1, group2, group3)), ~reduce(.x, intersect))
    

    就是你要找的

    my_list <- lst(group1, group2, group3)
    
    list_combination%>%
      mutate(result = map(cross(my_list),~reduce(.x,intersect)))
    
    # A tibble: 27 × 4
       group1  group2  group3  result   
       <chr>   <chr>   <chr>   <list>   
     1 module1 module1 module1 <chr [2]>
     2 module2 module1 module1 <chr [1]>
     3 module3 module1 module1 <chr [0]>
     4 module1 module2 module1 <chr [0]>
     5 module2 module2 module1 <chr [0]>
     6 module3 module2 module1 <chr [0]>
     7 module1 module3 module1 <chr [1]>
     8 module2 module3 module1 <chr [0]>
     9 module3 module3 module1 <chr [0]>
    10 module1 module1 module2 <chr [0]>
    # … with 17 more rows
    

    在基础R中:

     apply(expand.grid(my_list),1, Reduce,f=intersect)
    
    推荐文章