R data.table使用.I获取行号时返回NA

3
library(data.table)

dt <- data.table(A=c(NA,3,5,0,1,2),B=c("foo","foo","foo","bar","bar","bar"))

dt
#>     A   B
#> 1: NA foo
#> 2:  3 foo
#> 3:  5 foo
#> 4:  0 bar
#> 5:  1 bar
#> 6:  2 bar
#simple filter
dt[,.I[A>1]]
#> [1] NA  2  3  6

dt[A>1,which=TRUE]
#> [1] 2 3 6

我希望这两个应该返回相同的结果。

1个回答

5
前一种情况使用基本R逻辑进行子集筛选;后一种情况使用data.table略微不同的逻辑进行子集筛选。 data.table会从筛选中排除NA。
dt[A > 1]
#    A   B
# 1: 3 foo
# 2: 5 foo
# 3: 2 bar
# compare to base logic:
setDF(dt)
dt[dt$A > 1, ]
#     A    B
# NA NA <NA>
# 2   3  foo
# 3   5  foo
# 6   2  bar
setDT(dt)

如果您在第一条语句中添加一些诊断信息,可以更加清楚地看到它的作用:

dt[, {
    idx = A > 1
    print(idx)
    print(seq_len(.N)[idx])
    .I[A>1]
}]
# [1]    NA  TRUE  TRUE FALSE FALSE  TRUE
# [1] NA  2  3  6
# [1] NA  2  3  6
base 的逻辑是 NA 表示 "未知",因此在 NA 索引处保留还是去掉该元素也是未知的,因此输出需要是 NA。来自 ?"[":

索引中的 NAs

提取时,数值、逻辑或字符型的 NA 索引会选择一个未知元素,并在逻辑、整数、数字、复数或字符结果的相应元素中返回NA,以及对于列表则返回NULL。(原始结果返回 00。)

相对于来自 ?data.table

i

整数和逻辑向量的工作方式与 [.data.frame 相同,除了逻辑型的 NA 会被视为 FALSE


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接