我有一个模拟,有一个巨大的集合,并结合在中间的步骤.我使用plyr的ddply()函数原型化了这个过程,它非常适合我大部分的需求.但我需要加快聚合步骤,因为我必须运行10K模拟.我已经在并行扩展模拟,但如果这一步更快,我可以大大减少我需要的 node 数量.

以下是我试图做的合理简化:

library(Hmisc)

# Set up some example data
year <-    sample(1970:2008, 1e6, rep=T)
state <-   sample(1:50, 1e6, rep=T)
group1 <-  sample(1:6, 1e6, rep=T)
group2 <-  sample(1:3, 1e6, rep=T)
myFact <-  rnorm(100, 15, 1e6)
weights <- rnorm(1e6)
myDF <- data.frame(year, state, group1, group2, myFact, weights)

# this is the step I want to make faster
system.time(aggregateDF <- ddply(myDF, c("year", "state", "group1", "group2"),
                     function(df) wtd.mean(df$myFact, weights=df$weights)
                                 )
           )

感谢所有提示或建议!

推荐答案

您可以使用不可变的数据帧,而不是普通的R数据帧,它在创建子集时返回指向原始数据帧的指针,并且速度更快:

idf <- idata.frame(myDF)
system.time(aggregateDF <- ddply(idf, c("year", "state", "group1", "group2"),
   function(df) wtd.mean(df$myFact, weights=df$weights)))

#    user  system elapsed 
# 18.032   0.416  19.250 

如果我要编写一个专门针对这种情况定制的plyr函数,我会这样做:

system.time({
  ids <- id(myDF[c("year", "state", "group1", "group2")], drop = TRUE)
  data <- as.matrix(myDF[c("myFact", "weights")])
  indices <- plyr:::split_indices(seq_len(nrow(data)), ids, n = attr(ids, "n"))

  fun <- function(rows) {
    weighted.mean(data[rows, 1], data[rows, 2])
  }
  values <- vapply(indices, fun, numeric(1))

  labels <- myDF[match(seq_len(attr(ids, "n")), ids), 
    c("year", "state", "group1", "group2")]
  aggregateDF <- cbind(labels, values)
})

# user  system elapsed 
# 2.04    0.29    2.33 

它的速度要快得多,因为它避免了复制数据,在计算时只提取每次计算所需的子集.将数据转换为矩阵形式会带来另一个速度提升,因为矩阵子集比数据帧子集快得多.

R相关问答推荐

在处理因素时,Base R grep家族比stringr变体快得多

从字符载体创建函数参数

是否有任何解决方案可以优化VSCode中RScript的图形绘制?

在ggplot Likert条中添加水平线

查找图下的面积

更改编号列表的 colored颜色

在特定Quarto(reveal.js)幻灯片上隐藏徽标

使用tidy—select创建一个新的带有mutate的摘要变量

使用整齐的计算(curl -curl )和杂音

我如何才能找到FAMILY=POISSON(LINK=&Q;LOG&Q;)中的模型预测指定值的日期?

即使硬币没有被抛出,也要保持对其的跟踪

传递ggplot2的变量作为函数参数—没有映射级别以正确填充美学

用约翰逊分布进行均值比较

将一个字符串向量调整为与其他字符串向量完全相同的大小

给定开始日期和月份(数字),如何根据R中的开始日期和月数创建日期列

函数可以跨多个列搜索多个字符串并创建二进制输出变量

在另一个包中设置断点&S R函数

从数据创建数字的命名列表.R中的框

以任意顺序提取具有多个可能匹配项的组匹配项

在生成打印的自定义函数中,可以通过变量将线型或 colored颜色 设置为NULL吗?