r - 通过改变选定的列来计算 rowSums
问题描述
早上好,我被卡住了。
我有以下对象:
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"))
解决方案
你的陈述
我不能使用循环或 lapply,循环非常慢并且 lapply 内存效率不高。
这意味着您必须手动输入。考虑有效地使用循环,例如:
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
)。
推荐阅读
- macos - bower install 不会创建包含软件包的文件夹,即使它是使用 .bowerrc (Mac) 设置的
- apache-spark - 内存中的 DataFrame 寿命,Spark?
- c++ - c++ throw with try catch all always hits 在 C++ 11 14 和 17 中终止
- c++ - 从 C 样式数组初始化 STL 数组的最佳方法是什么?
- python - 如何将我的扭曲聊天链接到我的 github 网站?
- java - 读取 micronaut 方面的占位符
- c# - C# int 和仅包含 int 的结构之间的实际和理论差异
- python-3.x - 如何在 Python Pandas 的列中显示重复值的范围?
- linux - 在 docker run 中导出变量列表
- python - 如何查找 VALUE 列中有多少 TRUE 或 FALSE