我怎样才能让它发挥作用?
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)})
答案 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
可以更快地进行比较。