如何使用data.table执行“setdiff”合并?

11

假设我有两个表:

library(data.table)
set.seed(1)

tab1 <- data.table(
  let = rep(letters[1:2], each = 3),
  num = rep(1:3, 2),
  val = rnorm(6),
  key = c("let", "num")
)

tab2 <- data.table(
  let = rep(letters[1:2], each = 2),
  num = rep(1:2, 2),
  val = rnorm(4),
  key = c("let", "num")
)

表1:

> tab1
   let num        val
1:   a   1 -0.6264538
2:   a   2  0.1836433
3:   a   3 -0.8356286
4:   b   1  1.5952808
5:   b   2  0.3295078
6:   b   3 -0.8204684

表格2:

> tab2
   let num
1:   a   1
2:   a   2
3:   b   1
4:   b   2

有没有一种方法可以“合并”这些表格,以便我获得tab1中所有不在tab2中的结果?
   let num        val
1:   a   3 -0.8356286
2:   b   3 -0.8204684

2个回答

19

在这种情况下,它等同于一种反连接

tab1[!tab2, on=c("let", "num")]

但是setdiff()只会针对每个let,num的第一行。这在v1.9.8中被标记为FR #547


“on” 是否像 “setkey” 一样作为合并的操作? - Colonel Beauvel
鉴于我的示例已经设置了键,这可以简化为 tab1[!tab2] - sebastian-c
@ColonelBeauvel,是的,它支持即席连接。当您有大量数据且不想重新排序以进行连接时非常有用。或者当需要保留顺序时也很有用。此外,正在连接的列是清晰明确的(不像setkey可能会在代码的其他地方发生)。而且它是一个连接操作也是很明显的。 - Arun
1
@sebastian-c,我仍然更喜欢使用on=,这样以后就很清楚正在连接什么了。 - Arun
fsetdiff()已被实现-如此答案中所示。 - SymbolixAU
显示剩余2条评论

0
一种解决方案是进行合并,并删除其中包含tab2值的行。
d<-as.data.frame(merge(tab1,tab2,all=T))
t<-is.na(d[,4])
d[t,][,-4]

 let num      val.x
3   a   3 -0.8356286
6   b   3 -0.8204684

使用 data.table
merge(tab1,tab2,all=T)[is.na(val.y), 1:3]

 let num      val.x
1:   a   3 -0.8356286
2:   b   3 -0.8204684

这在这种情况下有效,但如果我的数据中有NA,它可能无法正常工作。 - sebastian-c

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接