2016-11-29 4 views
1

Die Frage ist ziemlich geradlinig, nicht sicher über die Lösung. Beispielcode für das, was ich versuche zu tun ist:R - cummean kombiniert mit weighted.mean

library(dplyr) 
# initialize a 
a = c(5, 6, 8, 9, 10, 15, 7, 9) 

# run cummean from dplyr, result 
round(cummean(a), digits = 2) 

[1] 5.00 5.50 6.33 7.00 7.60 8.83 8.57 8.62 

# run weighted.mean from base r, with weights passed as 2nd param 
weighted.mean(a, seq(1, length(a), by = 1)/sum(seq(1, length(a), by = 1))) 

[1] 9.388889 

Hier ist, wo mein Problem ein bisschen anders ist. Ich möchte einen mit den verschiedenen Gewichten gewichteten Cummean-Vektor berechnen. macht meine eigene Funktion für die Anzeige auf, und ein Gefühl von dem, was Ergebnis i zu erhalten suchen:

round(weighted.cummean(a), digits = 2) 

[1] 5.00, 5.67, 6.83, 7.70, 8.47, 10.33, 9.50, 9.39 

als Referenz auf, wie diese Werte berechnet werden, können Sie diese für-Schleife laufen mit weighted.mean in der Schleife für jede Berechnung:

b = c() 
for(i in 1:length(a)) { 
    weights = seq(1, i, by = 1)/sum(seq(1, i, by = 1)) 
    b = c(b, weighted.mean(a[1:i], weights)) 
} 

ich denke, meine Frage fasst zu - können wir die weighted.mean for-Schleife in einen 1-Liner von Code unter Verwendung cummean oder eine ähnliche Funktion wie cummean drehen?

Danke!

Antwort

4

Versuchen Sie diese:

w <- seq_along(a) 

cumsum(a * w)/cumsum(w) 
## [1] 5.000000 5.666667 6.833333 7.700000 8.466667 10.333333 9.500000 9.388889 

sapply(seq_along(a), function(i) weighted.mean(head(a, i), head(w, i))) 
## [1] 5.000000 5.666667 6.833333 7.700000 8.466667 10.333333 9.500000 9.388889 

out <- a; for(i in seq_along(a)) out[i] <- weighted.mean(head(a, i), head(w, i)); out 
## [1] 5.000000 5.666667 6.833333 7.700000 8.466667 10.333333 9.500000 9.388889 

library(dplyr) 
cummean(a * w)/cummean(w) 
## [1] 5.000000 5.666667 6.833333 7.700000 8.466667 10.333333 9.500000 9.388889 

library(zoo) 
rollapplyr(a, seq_along(a), function(x) weighted.mean(x, head(w, length(x)))) 
## [1] 5.000000 5.666667 6.833333 7.700000 8.466667 10.333333 9.500000 9.388889 
+0

Sie vielen Dank, das ist perfekt. Ich gehe mit der ersten Lösung, da ich mit dem Zoopaket nicht vertraut bin – Canovice