如何选择同时匹配另一个data.table中的两个条件的data.table中的行?

时间:2019-02-23 15:29:38

标签: r data.table

我有两个data.tables DT1DT2,其中DT1的列可能比DT2大,列也更多。我想选择DT1中的行,其中DT1的两列在DT2的两列的同一行中具有完全匹配。例如

DT1 = data.table(x=rep(c("b","a","c"),each=3), y=c(1,3,6), z=1:9)
DT2 = data.table(f=c("a","b"), g=c(1,3))

我正在寻找的输出DT1sub

   x y z
1: a 1 4
2: b 3 2

我的问题是,当我尝试对DT1进行子集化时,我还会得到那些只有一列匹配的行

> DT1[x%in%DT2$f & y%in%DT2$g]
#    x y z
# 1: b 1 1
# 2: b 3 2
# 3: a 1 4
# 4: a 3 5

我可以通过笨拙的DT1sub循环来获得所需的输出for

DT1sub<-c()
for (i in 1:2)
  DT1sub<-rbind(DT1sub,DT1[x==DT2$f[i] & y==DT2$g[i]])
DT1sub

但是我想知道是否有一个更智能的data.table版本。这可能很简单,但是我无法从example("data.table")中将其拼凑起来。

3 个答案:

答案 0 :(得分:3)

您在寻找吗?

library(data.table)

DT1sub <- DT1[DT2, on = .(x = f, y = g)]

输出:

   x y z
1: a 1 4
2: b 3 2

这基本上是一个过滤联接-仅保留x中与f中的任何内容匹配的行,以及yg中相同的行。

答案 1 :(得分:1)

另一个想法是使用setkey

library(data.table)

DT1 = data.table(x=rep(c("b","a","c"),each=3), y=c(1,3,6), z=1:9)
DT2 = data.table(f=c("a","b"), g=c(1,3))

setkey(DT1, x, y)
setkey(DT2, f, g)

DT1[DT2]
#    x y z
# 1: a 1 4
# 2: b 3 2

答案 2 :(得分:1)

上面的答案很好用,但我仍然更愿意使用merge()来完成此任务,因为它的参数更具表达力:

DT1sub <- merge(
  x = DT1, 
  y = DT2, 
  by.x = c('x', 'y'), by.y = c('f', 'g'), all.x = FALSE, all.y = FALSE)

当然,有些参数是多余的,因为它们是默认设置的,但是以这种方式写出来可以确保您记住是否已施加内部/外部联接等。