2
votes

Is there any fast function that is able to calculate a rolling average that is weighted? This is necessary because I have multiple observation (not always the same number) per data point (change in seconds) and I average that. When I take the rolling average, I want to re-weight to get an unbiased rolling average.

So far, I came up with this solution (in this example with a window of 3 seconds).

sam <- data.table(val_mean=c(1:15),N=c(11:25))

sam[,weighted:=val_mean*N]

sam[,rollnumerator:=rollapply(weighted,3,sum,fill=NA,align="left")]

sam[,rolldenominator:=rollapply(N,3,sum,fill=NA,align="left")]

sam[,rollnumerator/rolldenominator]

I couldn't find any question that already addresses this problem.

This is not about unequal spacing of the data: I can take care of that by expanding my data.table with NAs to include each second (the example above is equally spaced). Also, I don't want to include weights in the sense of RcppRoll's roll_mean: There, weights are fixed for all time windows ("A vector of length n, giving the weights for each element within a window."), while in my case the weights change according to the values currently processed. Thirdly, I don't want an adaptive window size, it should stay fixed (say at 3 seconds).

1

1 Answers

4
votes

1) Use by.column = FALSE:

library(data.table)
library(zoo)

wmean <- function(x) weighted.mean(x[, 1], x[, 2])
sam[, rollapplyr(.SD, 3, wmean, by.column = FALSE, fill = NA, align = "left")]

2) Another approach is to encode the values and weights into a complex vector:

wmean_cmplx <- function(x) weighted.mean(Re(x), Im(x))
sam[, rollapply(complex(real = val_mean, imag = N), 3, wmean_cmplx, 
  fill = NA, align = "left")]