2012-03-07 61 views
3

我是一个R新手,所以希望这是你们中的一些人可以解决的问题。 我有一个数据帧包含超过一百万个数据点。我的目标是以改变的起点计算加权平均数。替换for循环与应用以提高性能(与weighted.mean)

为了说明考虑这个帧(data.frame(矩阵(C(1,2,3,2,2,1),3,2)))

X1 X2 
1 1 2 
2 2 2 
3 3 1 

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

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

有了一个循环,我只是写道:

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命令来实现varry的起始点,这样performance就会增加?

问候, 鲁

+0

我不明白为什么你的数据框必须改变。如果您的实际数据与您的示例有一些重要差异,那么我们应该如何构建一个适用于您的真实数据的解决方案? – joran 2012-03-07 20:28:07

+0

对不起,这可能出错了。数据帧没有改变,但由于改变的起始点,在每次迭代中,为原始数据帧的新分部计算加权平均值。 – Ruben 2012-03-07 21:22:39

回答

3

建设,以产生正确的结果:

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

另外请注意,这是比sapply/lapply方法快

+0

对,我弄错了订单。做得很好! – joran 2012-03-07 21:56:53

+0

哇,谢谢。我正在写一些关于“反向cumsum”的文章,但事实正是如此。 – Ruben 2012-03-07 22:03:17

1

您可以使用lapply来创建你的子集,并sapply遍历所有这些,但我打赌会有一个更快的方法。在@ joran的回答

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

非常感谢您的回答!我知道必须有某种适用的变体才能起作用。我试图围绕它来实现它。它确实似乎工作。 – Ruben 2012-03-07 21:47:12