【问题标题】:Replacing for-loops with apply to improve perfomance (with weighted.mean)用 apply 替换 for 循环以提高性能(使用 weighted.mean)
【发布时间】:2012-03-25 09:00:54
【问题描述】:

我是 R 新手,所以希望这对你们中的一些人来说是一个可以解决的问题。 我有一个包含超过一百万个数据点的数据框。我的目标是计算起点变化的加权平均值。

为了说明考虑这个框架(data.frame(matrix(c(1,2,3,2,2,1),3,2)))

  X1 X2
1  1  2
2  2  2
3  3  1

其中 X1 是数据,X2 是采样权重。

我想计算 X1 从起点 1 到 3、2:3 和 3:3 的加权平均值。

我简单地写了一个循环:

B <- rep(NA,3) #empty result vector
for(i in 1:3){
  B[i] <- weighted.mean(x=A$X1[i:3],w=A$X2[i:3]) #shifting the starting point of the data and weights further to the end
} 

用我的真实数据这是不可能计算的,因为每次迭代都会改变 data.frame 并且计算需要几个小时而没有结果。

有没有办法用 apply 命令实现一个可变的起点,从而提高性能?

问候, 鲁本

【问题讨论】:

  • 我不明白为什么必须更改您的数据框。如果您的真实数据在某些重要方面与您的示例不同,我们应该如何构建一个适用于您的真实数据的解决方案?
  • 抱歉,这可能是错误的。数据框没有改变,但由于起始点的改变,在每次迭代中,都会为原始数据框的新子部分计算加权平均值。

标签: r for-loop apply weighted-average


【解决方案1】:

以@joran 的回答为基础产生正确的结果:

with(A, rev(cumsum(rev(X1*X2)) / cumsum(rev(X2))))
# [1] 1.800000 2.333333 3.000000

另请注意,这比sapply/lapply 方法快很多

【讨论】:

  • 哇,谢谢。我正在写一些关于“reverse cumsum”的东西,但就是这样。
【解决方案2】:

您可以使用lapply 创建您的子集,并使用sapply 循环这些子集,但我敢打赌会有更快的方法。

sapply(lapply(1:3,":",3),function(x) with(dat[x,],weighted.mean(X1,X2)))
[1] 1.800000 2.333333 3.000000

【讨论】:

  • 非常感谢您的回答!我知道必须有某种可行的应用变体。我正在努力解决它并实施它。它似乎确实有效。
猜你喜欢
  • 2019-03-16
  • 1970-01-01
  • 2021-05-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多