我有以下内容:
一种环境,其工作方式类似于数据框中行的哈希。例如,环境“inc”具有键“hello”,get("hello", envir = inc)
将返回“row1”“row2”“row50”,其中这些是数据帧中行的名称。在为环境中的键选择这些行之后,我想在它们上执行colSums。
环境有大约400,000个条目,我想根据这些colSums创建一个包含400,000行的新数据框。我有工作代码,基本上使用lapply / foreach来做这个,我已经在一小部分数据上使用它......但它的速度非常慢。就像......在使用doMC的3核上运行了20分钟,但仍未完成。这是代码:
incCounts <- foreach(key = ls(inc)) %dopar% {
transNames <- get(key, envir = inc)
transCounts <- df[transNames, ]
if ( ! is.null(dim(transCounts)) )
transCounts <- colSums(transCounts)
return(transCounts)
}
incCounts <- as.data.frame(t(simplify2array(incCounts)))
编辑:以下是我正在尝试使用data.frame和data.table的示例:
library(data.table)
set.seed(20)
transEnv <- new.env(hash = TRUE)
assign("hash1", paste("trans", 2:4, sep = ""), envir = transEnv)
assign("hash2", paste("trans", c(1, 3), sep = ""), envir = transEnv)
df <- data.frame(matrix(rnorm(5 * 4), nrow = 4, ncol = 5))
rownames(df) <- paste("trans", 1:4, sep = "")
colSums(df[transEnv$hash1, ]) # what I want
X1 X2 X3 X4 X5
0.9476963 -3.2149230 0.7603257 -1.8494967 1.7569055
dt <- data.table(trans = rownames(df), df)
setkey(dt, trans)
# This isn't working as I expected...
dt[transEnv$hash1, list(sum(X1), sum(X2), sum(X3), sum(X4), sum(X5))]
trans V1 V2 V3 V4 V5
[1,] trans2 -0.1444402 -1.4720633 -0.6135086 1.108451 1.24556891
[2,] trans3 0.7222297 -0.5961595 -0.2163115 -1.097342 0.08785472
[3,] trans4 0.3699069 -1.1467001 1.5901458 -1.860606 0.42348190
任何帮助将不胜感激!谢谢!
答案 0 :(得分:3)
可能适合data.table
。请参阅wiki point 5和this answer。如果您尝试使用,请从vignette('datatable-intro')
开始。
DT[,lapply(.SD,sum),by=grp]
要回答编辑,?data.table
的相关部分是:
高级:在
i
中传递这些组时,已知组子集的聚合效率特别高。当i
为data.table
时,DT[i,j]
会为j
的每一行评估i
。我们称之为i
,而不是通过dt[transEnv$hash1, list(sum(X1), sum(X2), sum(X3), sum(X4), sum(X5))]
进行分组。
所以而不是
dt[transEnv$hash1, list(sum(X1),sum(X2),sum(X3),sum(X4),sum(X5)), mult="last"]
尝试:
dt[transEnv$hash1][, list(sum(X1), sum(X2), sum(X3), sum(X4), sum(X5))]
,或者
dt[transEnv$hash1,lapply(.SD,sum),by="",.SDcols=names(dt)[-1]]
,或者
dt[transEnv$hash1][,trans:=NULL][,sapply(.SD,sum)]
,或者
{{1}}