2012-03-07 70 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