2

I want to use moving average function (rollmean) in R. Example data:

x<-seq(1,48,by=1)
y<-c(rep(11,12), rep(12,12))
z<-data.frame(x,y)

I want to calculate moving average of the z[,"x"] with lag of 3 days for each z[,"y"] (i.e. 11 & 12) and filled them to the (new) third column where first two rows of each z[,"y"] are designated by NAs.

Sven Hohenstein
  • 80,497
  • 17
  • 145
  • 168
Jack
  • 167
  • 2
  • 12
  • What have you tried? That could help you http://stackoverflow.com/questions/17765001/using-rollmean-when-there-are-missing-values-na – llrs Feb 06 '14 at 14:01
  • Any reason to use `data.table` instead of a dataframe? Why is `y` shorter than `x`? I'm pretty sure you can do this in one line using `rollapply(x, widths={something to do with y},...)` – Carl Witthoft Feb 06 '14 at 14:01

2 Answers2

6

Using zoo for example using the data.table package:

library(zoo)
library(data.table)
DT <- data.table(z)
DT[, roll_x := rollmeanr(x, 3, fill = NA), y]

Of course if have some missing values it is better to use rollapplyr :

DT[, roll_x := rollapplyr(x, 3, mean, fill = NA), y]

Another package that is going to be faster is caTools:

library(caTools)
DT[, roll_x := runmean(x, 3, align = 'right', endrule = 'NA'), by = y]

In terms of data frames this works too:

transform(z, roll_x = ave(x, y, FUN = function(x) rollmeanr(x, 3, fill = NA)))
eddi
  • 49,088
  • 6
  • 104
  • 155
agstudy
  • 119,832
  • 17
  • 199
  • 261
5

You can use the base function filter.

z[ , moving_average := filter(x, rep(1/3, 3), sides = 1), by = "y"]

Note that a lag of 3 results in two NAs.

Sven Hohenstein
  • 80,497
  • 17
  • 145
  • 168