表达式dt [is.na(dt)] = 0如何工作?

时间:2016-12-09 02:13:57

标签: r data.table

我正在尝试将NA个单元格替换为某个值但仅在一列中。我发现another thread解释了如何继续,但我不明白它是如何工作的。

is.na(dt)会返回跟踪原始dt的数据表,但会将所有值替换为TRUEFALSE,具体取决于原始单元格是NA 。现在,数据表第一个参数应该接受逻辑向量来选择行,而不是整个数据表。确实dt[is.na(dt)]会返回错误,但dt[is.na(dt)]=0会将所有NA值替换为0。为什么添加=0突然使此调用有效?它是特殊功能还是数据表设计的一部分。

1 个答案:

答案 0 :(得分:2)

如果表达式是data.frame

,表达式将起作用
dt[is.na(dt)]
#[1] NA NA NA NA NA

但是,在data.table中,语法不同,转换为逻辑矩阵效率低,不推荐v1.10.0

setDT(dt)[is.na(dt)]
  

[.data.table中的错误(setDT(dt),is.na(dt)):我是无效的类型   (矩阵)。也许将来一个2列矩阵可以返回一个列表   DT的元素(在FAQ 2.14中的A [B]的精神)。请让   数据表 - 帮助知道您是否喜欢这个,或添加您的

更好的选择是set,无需复制即可替换

for(j in seq_along(dt)) {
  set(dt, i = which(is.na(dt[[j]])), j = j, value = 0)
}   

dt
#    a b c
# 1: 1 0 2
# 2: 2 2 2
# 3: 2 1 1
# 4: 2 0 1
# 5: 0 1 2
# 6: 2 0 5
# 7: 1 1 4
# 8: 1 1 0
# 9: 2 1 5
#10: 2 1 1

或者是另一个版本

setDT(dt)[, lapply(.SD, function(x) replace(x, is.na(x), 0))]

数据

dt <- structure(list(a = c(1L, 2L, 2L, 2L, NA, 2L, 1L, 1L, 2L, 2L), 
b = c(NA, 2L, 1L, NA, 1L, NA, 1L, 1L, 1L, 1L), c = c(2L, 
2L, 1L, 1L, 2L, 5L, 4L, NA, 5L, 1L)), .Names = c("a", "b", 
"c"), class = "data.frame", row.names = c(NA, -10L))