这是我认为我应该在这个问题之后提出的问题。我想确认这是否是错误/不一致,然后再将其提交到 R-forge 跟踪器中。
考虑一下data.table
:
require(data.table)
DT <- data.table(x=c(1,0,NA), y=1:3)
现在,要访问 DT 中所有不为 0 的行,我们可以通过以下方式进行:
DT[x != 0]
# x y
# 1: 1 1
DT[!(x == 0)]
# x y
# 1: 1 1
# 2: NA 3
当底层逻辑操作等价时,访问DT[x != 0]
并给出不同的结果。DT[!(x==0)]
注意:将其转换为 data.frame 并运行这些操作将为两个逻辑等效操作提供彼此相同的结果,但该结果与这两个 data.table 结果不同。有关原因的解释,请查看?`[`
部分NAs in indexing
。
编辑:由于你们中的一些人强调与 相等data.frame
,这里是 data.frame 上相同操作的输出片段:
DF <- as.data.frame(DT)
# check ?`[` under the section `NAs in indexing` as to why this happens
DF[DF$x != 0, ]
# x y
# 1 1 1
# NA NA NA
DF[!(DF$x == 0), ]
# x y
# 1 1 1
# NA NA NA
我认为这是不一致的,两者都应该提供相同的结果。但是,哪个结果?的文档[.data.table
说:
i ---> 整数、逻辑或字符向量、列名表达式、列表或数据表。
整数和逻辑向量的工作方式与 [.data.frame. 除了逻辑 i 中的 NA 之外,它被视为 FALSE,并且单个 NA 逻辑不会被回收以匹配行数,就像在 [.data.frame.
很清楚为什么结果与对data.frame
. 但是,在 data.table 中,如果是这种情况,那么它们都应该返回:
# x y
# 1: 1 1
我浏览了[.data.table
源代码,现在明白了为什么会这样。有关发生这种情况的详细说明,请参阅 这篇文章。
简而言之,x != 0
评估为“逻辑”NA
并被替换为 FALSE。但是,!(x==0)
, first(x == 0)
被评估为逻辑NA
并被替换为 FALSE。然后否定发生,这导致NA
基本上成为TRUE
。
所以,我的第一个(或者说主要的)问题是,这是一个错误/不一致吗?如果是这样,我会将它作为一个归档在 data.table R-forge 跟踪器中。如果不是,我想知道造成这种差异的原因,并且我想建议对解释这种差异的文档进行更正(对已经很棒的文档!)。
编辑:跟进评论,第二个问题是,是否应该通过使用包含类似于??data.table
的列进行索引来处理子集化?(但我同意,根据@Roland 的评论,这很可能会引发意见,我完全可以不回答这个问题)。NA
data.frame