[R] Parameterising apply To Compute Rolling Average of Columns in a matrix

Ray Brownrigg Ray.Brownrigg at ecs.vuw.ac.nz
Wed Nov 17 20:44:10 CET 2010


On Thu, 18 Nov 2010, Paolo Rossi wrote:
> I sent a post to find a clever way to compute a Rolling Average of columns
> in a matrix  and I was given the solution below which I am very pleased
> with.
>
>
> RollingAverage <- function(x, RollingObs) {
>  cx <- cumsum(x);
>  N <- length(x);
>  Temp <- (cx[RollingObs:N] - c(0, cx[1:(N-RollingObs)]))/RollingObs
>  Output <- array(NA, N)
>  Output[RollingObs:N] <- Temp;
>  Output
>  }
>
>
> The only drawback is that in order to use apply to iterate over columns one
> needs to write a fucntion for any RollingObs unless one is able to pass a
> parameter through an apply call.
>
>  Example:
> a= array(1:100, dim = c(17,2))
> RollingAverage(a[, 1], 7)        # works fine
> apply(a, 2, RollingAverage)    # this doesnt work as it doesnt see
> RollingObs
>
> Is there a way to pass an additional parameter to apply?
>
RTFM.  Thats what the ... option of apply() is for.

apply(a, 2, RollingAverage, RollingObs=7)

Ray

> Thanks
>
> Paolo
>
> On 16 November 2010 20:05, Ray Brownrigg <Ray.Brownrigg at ecs.vuw.ac.nz>wrote:
> >  On Wed, 17 Nov 2010, Paolo Rossi wrote:
> > > Hi,
> > > Can anyone suggest a  clever way to compute a rolling weekly average of
> >
> > the
> >
> > > columns in a matrix?  The column bit is straightforward – use apply
> > > given
> >
> > a
> >
> > > function which does what you want on a column. With regard to a
> >
> > particular
> >
> > > column, the obvious way is to run a for loop indexing the last 7 days
> > > and computing the average . I simply would like to know if there is a 
> > > better
> >
> > /
> >
> > > quicker way.
> > >
> > >
> > >
> > > Code:
> > > Given a,
> > >
> > > > a= array(1:100, dim = c(17,2))
> > > > a
> > >
> > >       [,1] [,2]
> > >  [1,]    1   18
> > >  [2,]    2   19
> > >  [3,]    3   20
> > >  [4,]    4   21
> > >  [5,]    5   22
> > >  [6,]    6   23
> > >  [7,]    7   24
> > >  [8,]    8   25
> > >  [9,]    9   26
> > > [10,]   10   27
> > > [11,]   11   28
> > > [12,]   12   29
> > > [13,]   13   30
> > > [14,]   14   31
> > > [15,]   15   32
> > > [16,]   16   33
> > > [17,]   17   34
> > > one needs to start computing the average from obs 7 s (at obs 7 you
> > > have
> >
> > a
> >
> > > full week to compute the average) and compute the rolling weekly
> > > average from day 7 onwards
> > > Results will look like b
> > >       [,1] [,2]
> > >  [1,]    4   14
> > >  [2,]    5   21
> > >  [3,]    6   22
> > >  [4,]    7   23
> > >  [5,]    8   24
> > >  [6,]    9   25
> > >  [7,]   10   26
> > >  [8,]   11   27
> > >  [9,]   12   28
> > > [10,]   13   29
> > > Thanks in advance,
> >
> > I don't see how an average of 7 numbers all 18 or greater can be 14, as
> > in your
> > result[1, 2], unless you have mis-stated the question.
> >
> > Anyway, try:
> > apply(a, 2, function(x) {cx <- cumsum(x); N <- length(x); (cx[7:N] - c(0,
> > cx[1:(N-7)]))/7}
> >
> > HTH
> > Ray Brownrigg
> >
> > > Paolo



More information about the R-help mailing list