列表列中的data.table行比较

时间:2018-05-30 15:57:10

标签: r data.table

基本上我有一个带有列表列的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 个答案:

答案 0 :(得分:0)

不确定这是否有帮助。您可以先转换为长格式,然后为每个元素使用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