【问题标题】:Subset data.table by another data.table without merging all columns [duplicate]由另一个data.table子集data.table而不合并所有列[重复]
【发布时间】:2017-05-04 06:05:49
【问题描述】:

使用 data.table,我想根据另一个表对一个表进行子集化。

DT1 <- data.table( A = c(1:5,1:2), B = c(1,1,1,2,2,2,3), C = c(1:3))
DT2 <- data.table( A = c(1, 2, 3), B = c(1,3,1), D = c(4:6))

输出应该只包含第一个表的列。

   A B C
1: 1 1 1
2: 2 3 1
3: 3 1 3

使用合并功能,我得到两个表的列

merge(DT1, DT2, by = c("A", "B"))

       A B C D
    1: 1 1 1 4
    2: 2 3 1 5
    3: 3 1 3 6

由于我的数据集有更多的列,我正在寻找一种不使用合并函数但使用 data.table 语法 [i, j, by] 来获取结果的方法。 但是,对第一个表进行子集化后,它不会正确合并。

DT1[A %in% DT2[,A] & B %in% DT2[, B]]

       A B C
    1: 1 1 1
    2: 2 1 2    < wrong
    3: 3 1 3
    4: 2 3 1

DT1[A == DT2[,A] & B == DT2[, B]]
       A B C
    1: 1 1 1
    2: 3 1 3
    Warning messages:
    1: In A == DT2[, A] :
      longer object length is not a multiple of shorter object length
    2: In B == DT2[, B] :
      longer object length is not a multiple of shorter object length

有没有办法像合并一样获得正确的行,但使用 data.table 语法 [ ]?

【问题讨论】:

    标签: r merge data.table subset


    【解决方案1】:

    按照@akrun 的回答,您可以识别连接中的行并使用它们对表进行子集化:

    w = sort(DT1[DT2, on=.(A,B), which=TRUE, nomatch=0])
    DT1[w]
    
    #    A B C
    # 1: 1 1 1
    # 2: 3 1 3
    # 3: 2 3 1
    

    或更紧凑

    DT1[sort(DT1[DT2, on=.(A,B), which=TRUE, nomatch=0])]
    

    如果你想保持从 DT2 开始的顺序,不要排序;如果您想包含不匹配的行,请跳过nomatch=0

    【讨论】:

      【解决方案2】:

      我们先做一个连接,然后再做一个子集

      nm1 <- names(DT1)
      DT1[DT2, on = .(A, B)][, ..nm1]
      #   A B C
      #1: 1 1 1
      #2: 2 3 1
      #3: 3 1 3
      

      另外,这是semi_join 来自dplyr 的情况

      dplyr::semi_join(DT1, DT2, by = c('A', 'B'))
      #  A B C
      #1 1 1 1
      #2 2 3 1
      #3 3 1 3
      

      【讨论】:

      • DT1[DT1[DT2, on=.(A,B), which=TRUE, nomatch=0]]
      • @Frank 从来没有想过which 路线。很棒的选择。如果您想发布作为答案,请继续
      • 无钥匙加入的智能方式。 on= 参数对我来说是新的。谢谢!如果第二个表有不同的列名,比如DT3 &lt;- data.table( E = c(1, 2, 3), F = c(1,3,1), D = c(4:6)),它会是什么样子
      • @visu-l 在这种情况下,你会 od DT1[DT3, on =.(A=E, B=F)]
      • 能否解释一下第二条链[, ..nm1]。我没有找到关于“..”的文档
      【解决方案3】:
       setkey(DT1, A,B,C)
       DT1[DT2]
      # not quite right
         A B C
      1: 1 1 4
      2: 2 3 5
      3: 3 1 6
      # so join just on the two shared columns
      DT1[ DT2[,list(A,B)]  ]
         A B C
      1: 1 1 1
      2: 2 3 1
      3: 3 1 3
      

      查看DT2[,list(A,B)] 并看到在列表中命名所需列(不带引号)是获取列子集的常用方法。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-01-08
        • 1970-01-01
        • 2021-06-25
        • 1970-01-01
        • 1970-01-01
        • 2020-04-16
        • 2020-05-08
        • 2019-05-28
        相关资源
        最近更新 更多