Luc*_*ion 5 merge r list data.table
在R中,我有两个包含列表列的数据框
d1 <- data.table(
group_id1=1:4
)
d1$Cat_grouped <- list(letters[1:2],letters[3:2],letters[3:6],letters[11:12] )
Run Code Online (Sandbox Code Playgroud)
和
d_grouped <- data.table(
group_id2=1:4
)
d_grouped$Cat_grouped <- list(letters[1:5],letters[6:10],letters[1:2],letters[1] )
Run Code Online (Sandbox Code Playgroud)
我想合并这两个data.tables基于d1$Cat_grouped包含在向量中的向量d_grouped$Cat_grouped
更确切地说,可能有两个匹配标准:
a)每个向量的所有元素d1$Cat_grouped必须在匹配的向量中d_grouped$Cat_grouped
导致以下匹配:
result_a <- data.table(
group_id1=c(1,2)
group_id2=c(1,1)
)
Run Code Online (Sandbox Code Playgroud)
b)每个向量中的至少一个元素d1$Cat_grouped必须在匹配的向量中d_grouped$Cat_grouped
导致以下匹配:
result_b <- data.table(
group_id1=c(1,2,3,3),
group_id2=c(1,1,1,2)
)
Run Code Online (Sandbox Code Playgroud)
我该如何实现a)或b)?优选地,以数据表格的方式.
EDIT1:添加了a)和b)的预期结果
EDIT2:向d_grouped添加了更多组,因此分组变量重叠.这打破了一些建议的解决方案
这个答案集中在问题的a)部分。
它遵循Harland 的方法,但出于性能原因尝试更好地利用该data.table习惯用法,因为 OP 提到他的生产数据可能包含数百万个观察结果。
library(data.table)
d1 <- data.table(
group_id1 = 1:4,
Cat_grouped = list(letters[1:2], letters[3:2], letters[3:6], letters[11:12]))
d_grouped <- data.table(
group_id2 = 1:2,
Cat_grouped = list(letters[1:5], letters[6:10]))
Run Code Online (Sandbox Code Playgroud)
grp_cols <- c("group_id1", "group_id2")
unique(d1[, .(unlist(Cat_grouped), lengths(Cat_grouped)), by = group_id1][
d_grouped[, unlist(Cat_grouped), by = group_id2], on = "V1", nomatch = 0L][
, .(V2, .N), by = grp_cols][V2 == N, ..grp_cols])
group_id1 group_id2
1: 1 1
2: 2 1
Run Code Online (Sandbox Code Playgroud)
d1将和的列表元素扩展为长格式时,使用该函数d_grouped确定列表元素的数量。(注意与 的区别)获取列表中每个元素的长度,并在 R 3.2.0 中引入。d1lengths()lengths()length()
内连接(注意参数)之后,将针对 的每个组合nomatch = 0L计算结果集中的行数(使用特殊符号) 。仅考虑结果集中的计数与列表的原始长度匹配的那些行。最后,返回的唯一组合。.Ngrp_colsgrp_cols
结果 b) 可以通过省略计数内容从上述解决方案中导出:
unique(d1[, unlist(Cat_grouped), by = group_id1][
d_grouped[, unlist(Cat_grouped), by = group_id2], on = "V1", nomatch = 0L][
, c("group_id1", "group_id2")])
Run Code Online (Sandbox Code Playgroud)
Run Code Online (Sandbox Code Playgroud)group_id1 group_id2 1: 1 1 2: 2 1 3: 3 1 4: 3 2