r - 通过改变选定的列来计算 rowSums

标签 r data.table

早上好, 我被屏蔽了。

我有以下对象:

d1:
    a  b  d e
1:  0 32  0 1
2:  0 40  0 3
3: 23  0  0 2
4: 32  0 32 4
5:  0  0 56 0

w:
[[1]]
[1] "a" "b"

[[2]]
[1] "b" "d"

[[3]]
[1] "a" "b" "e"

我需要行的总和,仅使用单词中包含的列(对于每个“迭代”)

    a  b  d e f1 f2 f3
1:  0 32  0 1 32 32 33
2:  0 40  0 3 40 40 43
3: 23  0  0 2 23  0 25
4: 32  0 32 4 32 32 36
5:  0  0 56 0  0 56  0

d1[,f1:=rowSums(.SD),.SDcols=w[[1]]]

d1[,f2:=rowSums(.SD),.SDcols=w[[2]]]

d1[,f3:=rowSums(.SD),.SDcols=w[[3]]]

我无法使用循环或lapply,循环非常慢并且lapply内存效率不高。真实数据是一个 1112 行和 108968 列(最多)的矩阵以及超过 400 万个字符向量的列表。

谢谢!

数据

d1 <- read.table(h=T,strin=F,text=
"a  b  d e
 0 32  0 1
 0 40  0 3
23  0  0 2
32  0 32 4
 0  0 56 0")
data.table::setDT(d1)

w <- list(c("a","b"),c("b","d"),c("a","b","e"))

最佳答案

你的陈述

I can not use loops or lapply, the loops are very slow and lapply is not memory efficient.

意味着您必须手动输入。考虑有效地使用循环,例如这样:

for(i in seq_along(w)) {
  set(d1, i = NULL, j = paste0("f", i), value = rowSums(d1[, w[[i]], with=FALSE]))
}

结果是:

d1
#    a  b  d e f1 f2 f3
#1:  0 32  0 1 32 32 33
#2:  0 40  0 3 40 40 43
#3: 23  0  0 2 23  0 25
#4: 32  0 32 4 32 32 36
#5:  0  0 56 0  0 56  0

正如@Frank 在他的评论中提到的,在这种情况下替换是合适的

rowSums(d1[, w[[i]], with=FALSE])

Reduce("+", d1[, w[[i]], with=FALSE])

因为输入不是矩阵(并且rowSums将其输入强制转换为矩阵,如果它还不是)。实际上,这将是一种更有效的方法,但代价是无法轻松处理 NA 条目(就​​像在 rowSums 中可能实现的那样)。

关于r - 通过改变选定的列来计算 rowSums,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51402513/

相关文章:

r - 使用 `duplicated` 函数通过 key 识别 `data.table` 中的重复行

rmarkdown data.table 图在编译后不匹配

r - 如何在 R 中使用 Group By 和 order 函数

r - 将因子列转换为多个 bool 列

R - 带加权词的字符串距离

r - 在 Rcpp 中提取矩阵行

r - 使用docker时如何运行带有入口点的Rscript?

r - 如何在 R 中的 read_html 之后关闭未使用的连接

R:使用 for 循环遍历 data.table 中的变量名称(并按变量对它们进行分组)

r - 量子模型 3d 图形