使用data.table忽略NA值

时间:2015-04-28 19:25:26

标签: r data.table na

我怎样才能让它发挥作用?

library(data.table) 
RRR <-data.table(1:15,runif(15),rgeom(15,0.5),rbinom(15,2,0.5))

na.omit(RRR[(RRR==0)] <- NA)

我想用NA替换一些值(这里是== 0)。然后删除那些行。

或者如果您想运行基准测试,您可以使用更大的data.table:

set.seed(1)
n <- 1000000
RRR <- data.table(matrix(rgeom(100*n,0.5), ncol=100))

这个问题与以下内容有关: Selecting rows or columns with data.table R?

我刚刚意识到我在这里发布的问题与我上一天发布的问题正好相反(使用零获取行而不是没有任何零的行),这可能会让某些人感到困惑。
无论如何,我将继续问题,用零删除行,即尝试修复使用na.omit()的示例。

以下是您的贡献

na.omit(RRR[, lapply(.SD, function(x) replace(x, which(x==0), NA))])  ##akrun
user  system elapsed 
 2.12    0.17    2.31 

{ RRR[(RRR==0)] <- NA; na.omit(RRR) }   ##Frank
user  system elapsed 
 6.67    0.86    7.55    

{ for(j in 1:ncol(RRR)){ set(RRR, i=which(RRR[[j]]==0), j=j, value=NA)  } ;  na.omit(RRR) }  ##akrun
user  system elapsed 
  1.62    0.28    1.91 

RRR[, indx := as.logical(rowSums(.SD == 0))][(indx)]   ## David
user  system elapsed 
 2.89    0.36    3.25 

最快的是akrun循环(也许可以通过一些应用来改进),但它会修改原始数据。最简单的,也许更好的回答我的问题的是Franks建议{RRR [(RRR == 0)]&lt; - NA; na.omit(RRR)})

2 个答案:

答案 0 :(得分:5)

您可以尝试

library(data.table)
na.omit(RRR[, lapply(.SD, function(x) replace(x, which(x==0), NA))])

或使用set

for(j in 1:ncol(RRR)){
      set(RRR, i=which(RRR[[j]]==0), j=j, value=NA)
}
 na.omit(RRR)

基准

set.seed(1)
n <- 1000000
RRR <- data.table(matrix(rgeom(100*n,0.5), ncol=100))
RRR1 <- copy(RRR)
RRR2 <- copy(RRR)
RRR3 <- copy(RRR)

system.time({RRR[(RRR==0)] <- NA
             na.omit(RRR)})
#    user  system elapsed 
#  5.713   0.000   5.155 


system.time(na.omit(RRR1[, lapply(.SD, function(x) replace(x, 
        which(x==0), NA))]))
 #  user  system elapsed 
 #  3.000   0.000   2.337 

system.time({
 for(j in 1:ncol(RRR2)){
     set(RRR2, i=which(RRR2[[j]]==0), j=j, value=NA)
   }
  na.omit(RRR2)
  })

 # user  system elapsed 
 #  2.466   0.000   2.025 

##DavidArenburg's code from comments
 system.time(RRR3[, indx := !rowSums(.SD == 0)][(indx)])
 # user  system elapsed 
 #  0.000   0.000   2.796 

答案 1 :(得分:3)

如果你知道基础R:

,这是一种有效的方法
mmm <- as.matrix(RRR)
mmm[(mmm==0)] <- NA
na.omit(data.table(mmm))

据我所知,在第二行(与OP中的一行匹配)完成的矩阵式子集需要转换为矩阵。

效率。我的回答是@ akrun使用set的两倍。

类似这样的方法 - 限制遵循模式(1)替换为NA(2)按na.omit选择行 - 比直接选择行更糟糕(主题是OP的earlier question)。 @ DavidArenburg的代码的时间显示了这一点(复制自@ akrun的答案):RRR[, indx := !rowSums(.SD == 0)][(indx)]。因为我们正在与零进行比较,所以使用!.SD代替.SD==0可以更快地进行比较。