【发布时间】:2013-04-20 18:54:48
【问题描述】:
这是我认为我应该在this question 之后提出的问题。在将其提交到 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 相同操作的输出的sn-p:
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 源代码,现在了解为什么会发生这种情况。请参阅this post 了解为什么会发生这种情况的详细说明。
简而言之,x != 0 评估为“逻辑”,NA 被替换为 FALSE。但是,!(x==0),首先 (x == 0) 被评估为逻辑,NA 被替换为 FALSE。 然后否定发生,导致NA基本上变成TRUE。
所以,我的第一个(或者说主要的)问题是,这是一个错误/不一致吗?如果是这样,我会将它作为一个归档在 data.table R-forge 跟踪器中。如果不是,我想知道这种差异的原因,并且我想建议对解释这种差异的文档进行更正(对已经很棒的文档!)。
编辑: 跟进 cmets,第二个问题是,data.table 通过使用包含NA 的列进行索引来处理子集化是否类似于data.frame? (但我同意,根据@Roland 的评论,这可能会很好地引发意见,我完全可以不回答这个问题)。
【问题讨论】:
-
我投票赞成一个错误,因为我希望
data.table对象的行为与data.frame对象完全一样。 -
这个问题似乎要求投票/意见对我来说有点过分。
-
我强烈怀疑这是故意的,而不是错误;我也想看看它的文档/解释。现在我明白了(感谢您的解释:)),我有点喜欢当前的行为。不过,当我忘记它并因此而犯错时,我可能会改变主意。对于任何可以编辑的人:通过明智地使用空格和双反引号可以使帮助查询更正:
?`[`。此外,标题缺少“)”。 -
@Arun 如果它是一个错误或一个功能,对我来说似乎是主观的。这不是唯一的例子,data.table 的行为与 data.frame 不同。
-
@Roland,我想你没有完全理解/阅读这篇文章。我的疑虑不是关于 data.table 和 data.frame 本身之间的差异(我只是在 e4e5f4 和 Carl 的评论之后添加了这一点)。我的主要问题是关于 within
data.tablebetweendt[x != .]和dt[!(x==.)]当这些看似等效的操作时的差异。我现在在我的问题中大胆地提出了这一点。
标签: r dataframe data.table