如果你有一个缺少值的R data.table,你如何用值0替换所有这些值? E.g。
aa = data.table(V1=1:10,V2=c(1,2,2,3,3,3,4,4,4,4))
bb = data.table(V1=3:6,X=letters[1:4])
setkey(aa,V1)
setkey(bb,V1)
tt = bb[aa]
V1 X V2
1: 1 NA 1
2: 2 NA 2
3: 3 a 2
4: 4 b 3
5: 5 c 3
6: 6 d 3
7: 7 NA 4
8: 8 NA 4
9: 9 NA 4
10: 10 NA 4
任何方式在一行中执行此操作?如果它只是一个矩阵,你可以这样做:
tt[is.na(tt)] = 0
答案 0 :(得分:31)
is.na
(是一个原始的)具有相对非常少的开销,并且通常非常快。因此,您只需遍历列并使用set
替换NA with
0`。
使用<-
分配将导致所有列的副本,这不是使用data.table
的惯用方式。
首先,我将说明如何执行此操作然后显示慢如何可以获取大量数据(由于副本):
for (i in seq_along(tt)) set(tt, i=which(is.na(tt[[i]])), j=i, value=0)
这里会收到一个警告,“0”被强制转换为字符以匹配列的类型。你可以忽略它。
<-
:# by reference - idiomatic way
set.seed(45)
tt <- data.table(matrix(sample(c(NA, rnorm(10)), 1e7*3, TRUE), ncol=3))
tracemem(tt)
# modifies value by reference - no copy
system.time({
for (i in seq_along(tt))
set(tt, i=which(is.na(tt[[i]])), j=i, value=0)
})
# user system elapsed
# 0.284 0.083 0.386
# by copy - NOT the idiomatic way
set.seed(45)
tt <- data.table(matrix(sample(c(NA, rnorm(10)), 1e7*3, TRUE), ncol=3))
tracemem(tt)
# makes copy
system.time({tt[is.na(tt)] <- 0})
# a bunch of "tracemem" output showing the copies being made
# user system elapsed
# 4.110 0.976 5.187
答案 1 :(得分:13)
这里没什么不寻常的:
tt[is.na(tt)] = 0
..会起作用。
然而,这有点令人困惑:
tt[is.na(tt)]
...目前返回:
[.data.table
(tt,is.na(tt))中的错误:i是无效类型 (矩阵)。也许将来一个2列矩阵可以返回一个列表 DT的元素(在FAQ 2.14中的A [B]的精神)。请让 数据表 - 帮助知道您是否喜欢这样,或将您的评论添加到FR#1611。
答案 2 :(得分:0)
我会使用data.table
和lapply
,即:
tt[,lapply(.SD,function(kkk) ifelse(is.na(kkk),-666,kkk)),.SDcols=names(tt)]
屈服于:
V1 X V2
1: 1 -666 1
2: 2 -666 2
3: 3 a 2
4: 4 b 3
5: 5 c 3
6: 6 d 3
7: 7 -666 4
8: 8 -666 4
9: 9 -666 4
10: 10 -666 4
答案 3 :(得分:0)
OP发布的特定问题也可以通过
解决tt[is.na(X), X := 0]