data.table 用 NA 替换一个值

data.table replacing a value by NA

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

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

您可以尝试 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 循环,然后使用 replace

0 值更改为 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 值,将 1 替换为对应的 x 值,而 NA 将保持原样。

或者类似于 base R 的语法是

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

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

dt1[dt1==0] <- NA 为我工作。

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

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