代码之家  ›  专栏  ›  技术社区  ›  Fideldue

列表列中的data.table行比较

  •  0
  • Fideldue  · 技术社区  · 7 年前

    基本上,我有一个data.table,它有一个列表列,其中包含任何类型的向量条目,并且想知道一行的任何条目是否存在于所列向量的任何其他行中。并在最后得到一个带有分组变量的列。

    它的工作原理是 lapply() by = row.names() ,但当行数增加时,它当然会变得非常慢。 这个 paste() 目的是获取一个字符串,该字符串具有当前行的所有组合可能性,以便以后按其分组。

    还有更优雅(更快)的吗?解决方案?

    library(data.table)
    
    ex_dat <- data.table(
      ls_col = list(
        c(1,2,3),
        c(3,4),
        c(3,4,5,6,7,8),
        c(5)
      )
    )
    
    ex_dat[, grp_string := list(list(paste(unique(unlist(
      lapply(ex_dat[['ls_col']], function(x) {
        if (any(unlist(ls_col) %in% x)){
          x
        }
      }))), collapse = " | "))), 
      by = row.names(ex_dat)]
    

    当前输出和所需输出(分组变量可能有所不同):

    > ex_dat
            ls_col                    grp_string
    1:       1,2,3 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8
    2:         3,4 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8
    3: 3,4,5,6,7,8 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8
    4:           5         3 | 4 | 5 | 6 | 7 | 8
    
    1 回复  |  直到 7 年前
        1
  •  0
  •   chinsoon12    7 年前

    不确定这是否有用。可以先转换成长格式,然后对每个元素使用union

    ex_dat[, .(ls_col, elements=unlist(ls_col)), by=seq_len(ex_dat[,.N])][,
        .(members=Reduce(union, ls_col)), by=elements]
    

    结果(下一步的格式可能更简单):

        elements members
     1:        1       1
     2:        1       2
     3:        1       3
     4:        2       1
     5:        2       2
     6:        2       3
     7:        3       1
     8:        3       2
     9:        3       3
    10:        3       4
    11:        3       5
    12:        3       6
    13:        3       7
    14:        3       8
    15:        4       3
    16:        4       4
    17:        4       5
    18:        4       6
    19:        4       7
    20:        4       8
    21:        5       3
    22:        5       4
    23:        5       5
    24:        5       6
    25:        5       7
    26:        5       8
    27:        6       3
    28:        6       4
    29:        6       5
    30:        6       6
    31:        6       7
    32:        6       8
    33:        7       3
    34:        7       4
    35:        7       5
    36:        7       6
    37:        7       7
    38:        7       8
    39:        8       3
    40:        8       4
    41:        8       5
    42:        8       6
    43:        8       7
    44:        8       8
        elements members