【问题标题】:How to select rows in a data.table matching simultaneously two conditions in another data.table?如何选择同时匹配另一个 data.table 中的两个条件的 data.table 中的行?
【发布时间】:2019-02-23 15:29:37
【问题描述】:

我有两个 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") 拼凑起来。

【问题讨论】:

    标签: r data.table


    【解决方案1】:

    您在寻找:

    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 也是如此。

    【讨论】:

    • 正是我想要的。非常感谢!
    • 不客气!如果有帮助,请考虑接受答案。
    【解决方案2】:

    另一个想法是使用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
    

    【讨论】:

    • 太棒了,也非常感谢!使用 data.table 可以学到很多东西!
    【解决方案3】:

    以上答案效果很好,但我仍然更喜欢使用merge() 来完成这项任务,因为它的论点更具表现力:

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

    当然,有些参数是多余的,因为它们是默认设置的,但是这样写可以确保你记住你是否施加了内/外连接等。

    【讨论】:

    • 谢谢,这是对其他两个答案给出的更多速记代码的有用拼写。要看到它们都像合并操作一样操作,在我的问题中用第三列重新定义DT2 很有用,它将附加到DT1sub。例如。 DT2 = data.table(f=c("a","b"), g=c(1,3), k=c(1,2)).
    猜你喜欢
    • 1970-01-01
    • 2012-01-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-11
    • 1970-01-01
    • 1970-01-01
    • 2023-04-02
    相关资源
    最近更新 更多