由NaN进行的data.table子集不起作用

Wil*_*uck 5 r data.table

我在数据表中有一个包含NaN值的列.就像是:

my.dt <- data.table(x = c(NaN, NaN, NaN, .1, .2, .2, .3), y = c(2, 4, 6, 8, 10, 12, 14))
setkey(my.dt, x)
Run Code Online (Sandbox Code Playgroud)

我可以使用该J()函数来查找x列等于.2的所有实例

> my.dt[J(.2)]

     x  y
1: 0.2 10
2: 0.2 12
Run Code Online (Sandbox Code Playgroud)

但如果我尝试用NaN它做同样的事情就行不通.

> my.dt[J(NaN)]

     x  y
1: NaN NA
Run Code Online (Sandbox Code Playgroud)

我希望:

     x  y
1: NaN  2
2: NaN  4
3: NaN  6
Run Code Online (Sandbox Code Playgroud)

是什么赋予了?我在data.table文档中找不到任何解释为什么会发生这种情况的事情(尽管可能只是因为我不知道该寻找什么).有什么方法可以得到我想要的东西吗?最后,我想NaN用零替换所有值,使用类似的东西my.dt[J(NaN), x := 0]

Ric*_*rta 3

更新:这个问题不久前已在 v1.9.2 中修复。来自新闻

NANaN+Inf-Inf现在被视为不同的值,可以在键中,可以连接并且可以分组。data.table 定义:NA < NaN < -Inf。感谢 Martin Liberts 的建议,#4684、#4815 和 #4883。

require(data.table) ## 1.9.2+
my.dt[J(NaN)]
#      x  y
# 1: NaN  2
# 2: NaN  4
# 3: NaN  6
Run Code Online (Sandbox Code Playgroud)

这个问题一部分是设计选择,一部分是bug。有几个关于 SO 的问题,以及邮件列表上的几封电子邮件,探讨了 NA 的data.table关键。

常见问题解答中概述了主要思想,其中NA's 被视为FALSE

请随时参与邮件列表中的对话。@Arun 发起了一场对话,

http://r.789695.n4.nabble.com/Follow-up-on-subsetting-data-table-with-NAs-td4669097.html

此外,您还可以在以下任何问题的答案和评论中阅读更多内容:

使用 !=<some non-NA> 子集化 data.table 也会排除 NA
data.table 的 `i` 表达式中的 NA(可能的错误)
DT[!(x == .)] 和 DT[x != .] treat x 中的 NA 不一致


与此同时,您最好的选择是使用is.na.
虽然它比基数搜索慢,但它仍然比 中的大多数向量搜索快R,而且肯定比任何花哨的解决方法快得多。

library(microbenchmark)
microbenchmark(my.dt[.(1)], my.dt[is.na(ID)], my.dt[ID==1], my.dt[!!!(ID)])
# Unit: milliseconds
               expr    median 
        my.dt[.(1)]  1.309948 
   my.dt[is.na(ID)]  3.444689   <~~ Not bad
     my.dt[ID == 1]  4.005093 
 my.dt[!(!(!(ID)))] 10.038134 

### using the following for my.dt
my.dt <- as.data.table(replicate(20, sample(100, 1e5, TRUE)))
setnames(my.dt, 1, "ID")
my.dt[sample(1e5, 1e3), ID := NA]
setkey(my.dt, ID)
Run Code Online (Sandbox Code Playgroud)