使用 data.table 省略 NA 值

omitting NA values with data.table

我怎样才能让它工作?

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))

这个问题是关于:

我刚刚意识到我在这里发布的问题与我昨天发布的问题正好相反(获取带零的行与获取不带任何零的行),这可能会让一些人感到困惑人们。
无论如何,我将按原样继续问题,删除带零的行,即尝试修复使用 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 

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

你可以试试

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 

这是一种低效的方法,如果您知道基数 R 就有意义:

mmm <- as.matrix(RRR)
mmm[(mmm==0)] <- NA
na.omit(data.table(mmm))

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


效率。 我的回答花费的时间是@akrun 使用 set 的两倍。

像这样的方法——必须遵循模式 (1) 用 NA 替换 (2) select 行用 na.omit——比简单地 selecting 直接行(OP 的主题 )。这由@DavidArenburg 代码的时间显示(从@akrun 的回答复制到此处):RRR[, indx := !rowSums(.SD == 0)][(indx)]。因为我们正在与零进行比较,所以可以使用 !.SD 代替 .SD==0 来加快速度。