【问题标题】:Repeatedly sum a specific set of rows in data frame重复汇总数据框中的一组特定行
【发布时间】:2012-06-15 19:55:22
【问题描述】:

我有以下几点:

一种环境,其工作方式类似于数据框中行的哈希。例如,环境“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

任何帮助将不胜感激!谢谢!

【问题讨论】:

  • 内存不足了吗?另外,您是否尝试过不同的并行后端,例如 mclapply,而不是 foreach?

标签: r data.table


【解决方案1】:

可能适用于data.table。请参阅wiki point 5this answer。如果您确实尝试过,请从vignette('datatable-intro') 开始。

DT[,lapply(.SD,sum),by=grp]



回答编辑,?data.table的相关部分是:

高级:在i 中传递已知组的子集时,聚合这些组特别有效。当idata.table 时,DT[i,j]i 的每一行计算j。我们称之为不带 by 或按 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)] 

【讨论】:

  • 嗨,马修。这次真是万分感谢。因此,我创建了一个 data.table 并按“transNames”键对其进行排序。现在,我需要对除“transNames”之外的所有列进行 colSum。我实际上不能使用“by”,因为通过构造“transNames”是唯一的,而且我有太多不同的行组合,无法使用“by”。我只是想快速访问 data.frame 行。我尝试过类似DT[c("trans1", "trans2"), list(sum(V1), sum(V2))] 的操作,但这只会返回带有“trans1”和“trans2”行的 DT。建议?谢谢!
  • @Harold 恐怕我不关注。您能否提供一个小的示例数据集来说明输入和所需的输出。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-10-23
  • 1970-01-01
  • 2017-06-15
相关资源
最近更新 更多