data.table如何将一个数值替换为NA?

10

我想在data.table的每一列中将0替换为NA

library(data.table)
dt1 <- data.table(V1=0:2, V2=2:0)
dt1

   V1 V2
1:  0  2
2:  1  1
3:  2  0

dt1==0
       V1    V2
[1,]  TRUE FALSE
[2,] FALSE FALSE
[3,] FALSE  TRUE

我试过这个

dt1[dt1==0] 
Error in `[.data.table`(dt1, dt1 == 0) : 
  i is invalid type (matrix). Perhaps in future a 2 column matrix could return a list of elements of DT (in the spirit of A[B] in FAQ 2.14). Please let datatable-help know if you'd like this, or add your comments to FR #1611.

并且我也尝试了这个

dt1[dt1==0, .SD :=NA] 

编辑过

部分sessionInfo()内容

R version 3.2.1 (2015-06-18)
Platform: i686-pc-linux-gnu (32-bit)
Running under: Ubuntu 14.04.2 LTS

data.table_1.9.4
2个回答

20

您可以尝试使用set来处理多列数据。由于避免了[.data.table的开销,因此速度会更快。

for(j in seq_along(dt1)){
         set(dt1, i=which(dt1[[j]]==0), j=j, value=NA)
}
dt1
#   V1 V2
#1: NA  2
#2:  1  1
#3:  2 NA

另一种选择是使用lapply循环,然后使用replace0值更改为NA。

dt1[, lapply(.SD, function(x) replace(x, which(x==0), NA))]

或者我们可以利用一些算术操作将0值转换为NA。

 dt1[, lapply(.SD, function(x) (NA^!x) *x)]

(NA^!x)*x的工作方式是将!x转换为逻辑TRUE/FALSE向量,其中每列的TRUE对应于0值,变为NA和1,即NA^!x。通过乘以x值,我们用x值替换1(对应的x值),而NA将保持不变。

或者一个类似于base R 的语法会是:

  is.na(dt1) <- dt1==0

但是对于大的data.table,这种方法可能不太高效,因为dt1==0会生成一个逻辑矩阵,而且正如@Roland在评论中提到的那样,数据集会被复制。我会在更大的数据集上使用基于lapply或更高效的set的方法。


1
如果您有一个大矩阵并且想避免内存使用过高,那么您需要在循环中添加gc()。 - tafelplankje

3

dt1[dt1==0] <- NA worked for me.

dt1[dt1==0] <- NA
dt1
##   V1 V2
##1: NA  2
##2:  1  1
##3:  2 NA

如 Roland 所指出的,这确实会复制 data.table 对象,并且速度较慢。

我也是这样做,但dt1[dt1==0]会出错。 - MYaseen208
这对我来说不起作用。不知道为什么? - MYaseen208
2
不要这样做。它会复制整个数据表,当数据表足够大时会很慢。 - Roland
@Roland 谢谢,好知道! - alexforrence

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