Tutorial :Calculating moving average



Question:

I'm trying to use R to calculate the moving average over a series of values in a matrix. The normal R mailing list search hasn't been very helpful though. There doesn't seem to be a built-in function in R will allow me to calculate moving averages. Do any packages provide one? Or do I need to write my own?


Solution:1

  • Rolling Means/Maximums/Medians in the zoo package (rollmean)
  • MovingAverages in TTR
  • ma in forecast


Solution:2

Or you can simply calculate it using filter, here's the function I use:

ma <- function(x,n=5){filter(x,rep(1/n,n), sides=2)}


Solution:3

Using cumsum should be sufficient and efficient. Assuming you have a vector x and you want a running sum of n numbers

cx <- c(0,cumsum(x))  rsum <- (cx[(n+1):length(cx)] - cx[1:(length(cx) - n)]) / n  


Solution:4

You could use RcppRoll for very quick moving averages written in C++. Just call the roll_mean function. Docs can be found here.

Otherwisem, this (slower) for loop should do the trick.

ma <- function(arr, n=15){    res = arr    for(i in n:length(arr)){      res[i] = mean(arr[(i-n):i])    }    res  }  


Solution:5

The caTools package has very fast rolling mean/min/max/sd and few other functions. I've only worked with runmean and runsd and they are the fastest of any of the other packages mentioned to date.


Solution:6

In fact RcppRoll is very good.

The code posted by cantdutchthis must be corrected in the fourth line to the window be fixed:

ma <- function(arr, n=15){    res = arr    for(i in n:length(arr)){      res[i] = mean(arr[(i-n+1):i])    }    res  }  

Another way, which handles missings, is given here.

A third way, improving cantdutchthis code to calculate partial averages or not, follows:

  ma <- function(x, n=2,parcial=TRUE){    res = x #set the first values      if (parcial==TRUE){      for(i in 1:length(x)){        t<-max(i-n+1,1)        res[i] = mean(x[t:i])      }      res      }else{      for(i in 1:length(x)){        t<-max(i-n+1,1)        res[i] = mean(x[t:i])      }      res[-c(seq(1,n-1,1))] #remove the n-1 first,i.e., res[c(-3,-4,...)]    }  }  


Solution:7

In order to complement the answer of cantdutchthis and Rodrigo Remedio;

moving_fun <- function(x, w, FUN, ...) {    # x: a double vector    # w: the length of the window, i.e., the section of the vector selected to apply FUN    # FUN: a function that takes a vector and return a summarize value, e.g., mean, sum, etc.    # Given a double type vector apply a FUN over a moving window from left to the right,     #    when a window boundary is not a legal section, i.e. lower_bound and i (upper bound)     #    are not contained in the length of the vector, return a NA_real_    if (w < 1) {      stop("The length of the window 'w' must be greater than 0")    }    output <- x    for (i in 1:length(x)) {       # plus 1 because the index is inclusive with the upper_bound 'i'      lower_bound <- i - w + 1      if (lower_bound < 1) {        output[i] <- NA_real_      } else {        output[i] <- FUN(x[lower_bound:i, ...])      }    }    output  }    # example  v <- seq(1:10)    # compute a MA(2)  moving_fun(v, 2, mean)    # compute moving sum of two periods  moving_fun(v, 2, sum)  


Solution:8

all the options listed here are causal moving averages. if a non causal version is required, then the package signal has some options.


Note:If u also have question or solution just comment us below or mail us on toontricks1994@gmail.com
Previous
Next Post »