【问题标题】:non-joins with data.tables与 data.tables 的非连接
【发布时间】:2011-12-16 18:25:17
【问题描述】:

我对 data.table 的“非连接”习语有疑问,灵感来自迭代器的 question。这是一个例子:

library(data.table)

dt1 <- data.table(A1=letters[1:10], B1=sample(1:5,10, replace=TRUE))
dt2 <- data.table(A2=letters[c(1:5, 11:15)], B2=sample(1:5,10, replace=TRUE))

setkey(dt1, A1)
setkey(dt2, A2)

data.tables 看起来像这样

> dt1               > dt2
      A1 B1               A2 B2
 [1,]  a  1          [1,]  a  2
 [2,]  b  4          [2,]  b  5
 [3,]  c  2          [3,]  c  2
 [4,]  d  5          [4,]  d  1
 [5,]  e  1          [5,]  e  1
 [6,]  f  2          [6,]  k  5
 [7,]  g  3          [7,]  l  2
 [8,]  h  3          [8,]  m  4
 [9,]  i  2          [9,]  n  1
[10,]  j  4         [10,]  o  1

要查找dt2 中的哪些行与dt1 中的键相同,请将which 选项设置为TRUE

> dt1[dt2, which=TRUE]
[1]  1  2  3  4  5 NA NA NA NA NA

Matthew 在这个 answer 中建议,这是一个“非加入”成语

dt1[-dt1[dt2, which=TRUE]]

dt1 子集到那些具有未出现在dt2 中的索引的行。在我的机器上使用data.table v1.7.1 我得到一个错误:

Error in `[.default`(x[[s]], irows): only 0's may be mixed with negative subscripts

相反,使用选项 nomatch=0,“非连接”有效

> dt1[-dt1[dt2, which=TRUE, nomatch=0]]
     A1 B1
[1,]  f  2
[2,]  g  3
[3,]  h  3
[4,]  i  2
[5,]  j  4

这是预期的行为吗?

【问题讨论】:

  • 刚刚添加到 v1.8.3 的是 not-join 语法。在这种情况下dt1[!dt2]。将添加一个详细的答案...

标签: r data.table


【解决方案1】:

v1.8.3 中的新功能:

A new "!" prefix on i signals 'not-join' (a.k.a. 'not-where'), #1384.
  DT[-DT["a", which=TRUE, nomatch=0]]   # old not-join idiom, still works
  DT[!"a"]                              # same result, now preferred.
  DT[!J(6),...]                         # !J == not-join
  DT[!2:3,...]                          # ! on all types of i
  DT[colA!=6L | colB!=23L,...]          # multiple vector scanning approach
  DT[!J(6L,23L)]                        # same result, faster binary search
'!' has been used rather than '-' :
  * to match the 'not-join' and 'not-where' nomenclature
  * with '-', DT[-0] would return DT rather than DT[0] and not be backwards
    compatibile. With '!', DT[!0] returns DT both before (since !0 is TRUE in
    base R) and after this new feature.
  * to leave DT[+...] and DT[-...] available for future use

【讨论】:

    【解决方案2】:

    据我所知,这是基础 R 的一部分。

    # This works
    (1:4)[c(-2,-3)]
    
    # But this gives you the same error you described above
    (1:4)[c(-2, -3, NA)]
    # Error in (1:4)[c(-2, -3, NA)] : 
    #   only 0's may be mixed with negative subscripts
    

    文本错误消息表明它预期的行为。

    这是我对为什么这是预期行为的最佳猜测:

    从他们在别处对待NA 的方式来看(例如,通常默认为na.rm=FALSE),R 的设计者似乎将NA 视为携带重要信息,并且不愿意在没有明确说明的情况下放弃它这样做。 (幸运的是,设置 nomatch=0 为您提供了一种清晰的方式来传递该指令!)

    在这种情况下,设计者的偏好可能解释了为什么NA 被接受为正索引,而不是负索引:

    # Positive indexing: works, because the return value retains info about NA's
    (1:4)[c(2,3,NA)]
    
    # Negative indexing: doesn't work, because it can't easily retain such info
    (1:4)[c(-2,-3,NA)]
    

    【讨论】:

    • +1 不错的答案!是的,它来自基地。 FR#1384 是使 X[-Y] 语法意味着“不加入”。同时需要which=TRUE,nomatch=0
    【解决方案3】:

    data.table 1.7.3 版中的新功能:

    新选项 datatable.nomatch 允许 nomatch 的默认值是 从 NA 更改为 0,...

    【讨论】:

    • 这种变化可能会有所帮助,但并不是真正的“不加入”。 FR#1384 仍有待完成。很高兴看到有人读新闻 :)
    猜你喜欢
    • 2012-12-17
    • 2014-05-07
    • 1970-01-01
    • 2021-02-03
    • 1970-01-01
    • 1970-01-01
    • 2016-10-24
    • 2020-09-24
    • 2022-01-09
    相关资源
    最近更新 更多