【问题标题】:NA in `i` expression of data.table (possible bug) [duplicate]data.table 的“i”表达式中的 NA(可能的错误)[重复]
【发布时间】:2013-07-06 23:52:39
【问题描述】:

i 包含NA 时,不会返回该特定行。我不确定这是预期的行为还是它?

require(data.table)
x = data.table(a=c(NA, 1:3, NA))    
x[a>0]       
   a
1: 1
2: 2
3: 3

x[!(a>0)]
    a
1: NA
2: NA

x[a<0]   
Empty data.table (0 rows) of 1 col: a

x[!(a<0)]
    a
1: NA
2:  1
3:  2
4:  3
5: NA

 > sessionInfo()
 R version 2.15.2 (2012-10-26)
 Platform: x86_64-unknown-linux-gnu (64-bit)

 locale:
  [1] LC_CTYPE=en_US.UTF-8       LC_NUMERIC=C              
  [3] LC_TIME=en_US.UTF-8        LC_COLLATE=en_US.UTF-8    
  [5] LC_MONETARY=en_US.UTF-8    LC_MESSAGES=en_US.UTF-8   
  [7] LC_PAPER=C                 LC_NAME=C                 
  [9] LC_ADDRESS=C               LC_TELEPHONE=C            
  [11] LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C       

 attached base packages:
  [1] stats     graphics  grDevices utils     datasets  methods   base     

 other attached packages:
  [1] data.table_1.8.8

【问题讨论】:

  • 有趣...我可以建议您在示例中使用a=c(NA, 1:3, NA) 吗?有这么长的例子是没有用的或相关的。
  • 换一种说法,x[as.logical(a)]x[!!as.logical(a)] 给出的结果不同。很想把它称为一个错误。在这种情况下,我强烈建议您确保使用最新版本的软件包并将该信息(版本号)添加到您的问题中。
  • x[as.logical(!a&lt;0)] 似乎删除了 NA 值...
  • 刚刚更新了更小的示例和一些其他结果
  • 我认为这也更相关:stackoverflow.com/questions/16239153/…

标签: r data.table


【解决方案1】:

正如@flodel 指出的那样,问题可以简化为,为什么这不是TRUE

identical(x[as.logical(a)], x[!!as.logical(a)])   # note the double bangs

答案在于data.table如何处理i中的NA,以及如何处理i中的!。两者都受到特殊待遇。问题确实出现在两者的结合中。

  • i 中的NA 被视为FALSE
  • ! in i 被视为否定。

这在?.data.table 中有详细记录(正如 G. Grothendieck 在另一个答案中指出的那样)。 相关部分是:

整数和逻辑向量的工作方式与 [.data.frame.除了逻辑 i 中的 NA 之外,它被视为 FALSE,并且单个 NA 逻辑不会被回收以匹配行数,就像在 [.data.frame 中一样。
...
所有类型的 'i' 都可以以 ! 为前缀。这表示应该执行不加入或不选择。在整个 data.table 文档中,我们提到“i”的类型时,我们指的是“!”之后的“i”类型(如果存在)。

如果您查看[.data.table 的代码,! 的处理方式(如果存在)是由

  1. 删除前面的!
  2. 解释剩余的i
  3. 否定这种解释

处理NAs 的方式是将这些值设置为FALSE
然而——而且非常重要的是——这发生在上面的第 2 步中。

因此,真正发生的情况是,当i 包含NA 并且i! 为前缀时,NA 被有效地解释为TRUE。虽然从技术上讲,这是记录在案的,但我不确定这是否符合预期。


当然还有@flodel的最后一个问题:为什么x[as.logical(a)]x[!!as.logical(a)]不一样?这样做的原因是只有 first bang 得到特殊处理。第二次爆炸被R 解释为正常。

由于!NA仍然是NA,对!!(NA)的解释修改顺序为:

!!(NA)  
!( !(NA) )  
!(  NA   )
!( FALSE )
TRUE

【讨论】:

    【解决方案2】:

    这是记录在案的行为。请参阅?data.table 中对i 参数的描述。

    【讨论】:

    • Gabor,我认为记录在案的内容可能与我们在这里看到的略有不同。具体来说,我认为@flodel 的评论非常相关。相反,“NA 被解释为 FALSE”应该出现在 ! 之后。即!NA 应该和NA 一样对待
    • 同意。是否扔掉NA 是一个记录在案的设计选择。 [.data.frame 保留它们,而 [.data.tablesubset 都没有。没有错。问题是data.table 在执行一致的逻辑规则方面似乎存在严重问题。我发现subset(x, as.logical(a))subset(x, !!as.logical(a)) 返回相同的结果是正常/直观的。但是,对于[.data.tablex[as.logical(a)]x[!!as.logical(a)],不要...
    • 还有功能请求和@MatthewDowle 的回答的最后一段:stackoverflow.com/questions/16221742/… 让我非常不舒服。其中大部分似乎依赖于错误的(或新的?)概念,即 !NA 应该是 TRUE
    • @flodel,你可以看到上面链接的帖子的后续(广泛)讨论here。 IIUC,我们应该期待一些变化。
    • @Arun。这是现场。感谢您提请作者注意。
    猜你喜欢
    • 2014-03-18
    • 1970-01-01
    • 1970-01-01
    • 2018-09-01
    • 2022-11-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-26
    相关资源
    最近更新 更多