R:data.table 计数 !NA 每行

标签 r data.table

我正在尝试计算每行不包含 NA 的列数,并将该值放入该行的新列中。

示例数据:

library(data.table)

a = c(1,2,3,4,NA)
b = c(6,NA,8,9,10)
c = c(11,12,NA,14,15)
d = data.table(a,b,c)

> d 
    a  b  c
1:  1  6 11
2:  2 NA 12
3:  3  8 NA
4:  4  9 14
5: NA 10 15

我想要的输出将包括一个新列 num_obs其中包含每行的非 NA 条目数:
    a  b  c num_obs
1:  1  6 11       3
2:  2 NA 12       2
3:  3  8 NA       2
4:  4  9 14       3
5: NA 10 15       2

我已经读了几个小时了,到目前为止,我想到的最好的方法是遍历行,我知道在 R 或 data.table 中永远不建议这样做。我相信有更好的方法可以做到这一点,请赐教。

我的糟糕方式:
len = (1:NROW(d))
for (n in len) {
  d[n, num_obs := length(which(!is.na(d[n])))]
}

最佳答案

使用 Reduce 试试这个链接在一起 +调用:

d[, num_obs := Reduce(`+`, lapply(.SD,function(x) !is.na(x)))]

如果速度很重要,您可以通过 Ananda 的建议来进一步了解对正在评估的列数进行硬编码:
d[, num_obs := 4 - Reduce("+", lapply(.SD, is.na))]

使用 Ananda 的较大数据进行基准测试。表 d从上面:
fun1 <- function(indt) indt[, num_obs := rowSums(!is.na(indt))][]
fun3 <- function(indt) indt[, num_obs := Reduce(`+`, lapply(.SD,function(x) !is.na(x)))][]
fun4 <- function(indt) indt[, num_obs := 4 - Reduce("+", lapply(.SD, is.na))][]

library(microbenchmark)
microbenchmark(fun1(copy(d)), fun3(copy(d)), fun4(copy(d)), times=10L)

#Unit: milliseconds
#          expr      min       lq     mean   median       uq      max neval
# fun1(copy(d)) 3.565866 3.639361 3.912554 3.703091 4.023724 4.596130    10
# fun3(copy(d)) 2.543878 2.611745 2.973861 2.664550 3.657239 4.011475    10
# fun4(copy(d)) 2.265786 2.293927 2.798597 2.345242 3.385437 4.128339    10

关于R:data.table 计数 !NA 每行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35306500/

相关文章:

r - 将大矩阵保存为 csv 文件 - excel 中多行的标题

r - 概率多项选择测试,sliderInputs 总和为 1 个约束

r - 将函数列表应用于 R 中 data.table 的每一列

r - 当变量名称存储在字符向量中时选择/分配给 data.table

r - 如何优化批量预测

R:在 R 中改变和弦图的颜色

r - 错误 : Could not find build tools necessary to build dplyr

r - 性能:结合大数据表

使用 data.table 在 R 中重建索引?

r - 如何在 R 中转换为 "tableau"格式?