首页 > 解决方案 > R data.table 使用 .I 获取行号时返回 NA

问题描述

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

我期待这两个应该返回相同的结果。

标签: rdata.table

解决方案


前一种情况使用baseR 逻辑进行子集化;后一种情况使用data.table's 略有不同的子集逻辑。

data.tableNA从过滤中排除:

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。来自?"["

索引中的 NA

提取时,数字、逻辑或字符NA索引选择未知元素,因此返回NA逻辑、整数、数字、复数或字符结果的相应元素,并返回NULL列表。(它返回00原始结果。)

与来自?data.table

i

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


推荐阅读