Canovice Canovice - 11 days ago 7
R Question

R - cummean combined with weighted.mean

Question is fairly straight-forward, not sure about the solution. Example code for what I am trying to do is:

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


Here's where my problem is a bit different. I would like to calculate a cummean vector weighted by the different weights. making up my own function for display purposes, and to get a sense of what result i am looking for:

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

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


For reference on how these values are being calculated, you can run this for-loop using weighted.mean in the loop for each calculation:

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))
}


i guess my question summarizes to - can we turn the weighted.mean for-loop into a 1-liner of code using cummean or a function similar to cummean?

Thanks!

Answer

Try these:

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

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) sum(x * prop.table(head(w, length(x)))))
## [1]  5.000000  5.666667  6.833333  7.700000  8.466667 10.333333  9.500000  9.388889