[R] using "rollapply" to calculate a moving sum or running sum?

Enrico Schumann es at enricoschumann.net
Sat Aug 3 13:16:18 CEST 2013


On Fri, 02 Aug 2013, Anika Masters <anika.masters at gmail.com> writes:

> This is not critical, but I am curious to learn. Are there any
> suggestions for speeding up the process to calculate a moving row sum?
> (Ideally from within R, as opposed to suing C, etc.)
> Using rollapply on a matrix of 45,000 rows and 400 columns takes 83 minutes.
>
> date()
> mymatrix <- matrix(data=1:45000, nrow=45000, ncol=400)
> temp <- t(rollapply(t(mymatrix), width=12, FUN=sum, by.column=T,
> fill=NA, partial=FALSE, align="left"))
> date()
>

Write a function that *quickly* computes the moving sum of a single row;
then loop over the rows.

Here is such a function, which is a slightly modified copy of the
function MA ("moving average") in the NMOF package.

  rsum <- function (y, order, pad = NULL) {
      n <- length(y)
      ma <- cumsum(y)
      ma[order:n] <- ma[order:n] - c(0, ma[1L:(n - order)])
      if (!is.null(pad) && order > 1L) 
          ma[1L:(order - 1L)] <- pad
      ma
  }

The main 'trick' is the use of 'cumsum'.  Some speed comparions can
given here

  require("NMOF")
  showExample("fastMA")

The original function computes a moving average but is "right-aligned"
(which I typically want for time series).  Since in your example you use
'align = "left"', I flip the columns of your matrix left to right.

Your example (increase the size by increasing rows/cols):

  require("zoo")

  ## data
  rows <- 450
  cols <- 40
  mymatrix <- matrix(data = rnorm(rows*cols), nrow = rows, ncol = cols)
  
  ## with rollapply
  temp <- t(rollapply(t(mymatrix), width=12, FUN=sum, by.column=T,
                      fill=NA, partial=FALSE, align="left"))
  
  ## with rsum
  answer <- array(NA, dim = dim(mymatrix))
  flipped <- mymatrix[ ,cols:1]
  for (i in seq_len(rows))
      answer[i, ] <- rsum(flipped[i, ], 12, NA)
  all.equal(unname(temp), answer[ ,cols:1])




Regards,
        Enrico



> On Thu, Jun 27, 2013 at 2:41 PM, arun <smartpink111 at yahoo.com> wrote:
>> Hi,
>> Try:
>> library(zoo)
>>
>> rollapply(t(mymatrix),width=12,FUN=sum,by.column=T,fill=NA,partial=FALSE,align="left")
>>  #     [,1] [,2] [,3] [,4] [,5]
>>  #[1,]  342  354  366  378  390
>>  #[2,]  402  414  426  438  450
>>  #[3,]  462  474  486  498  510
>>  #[4,]  522  534  546  558  570
>>  #[5,]  582  594  606  618  630
>>  #[6,]  642  654  666  678  690
>>  #[7,]  702  714  726  738  750
>>  #[8,]  762  774  786  798  810
>>  #[9,]  822  834  846  858  870
>> #[10,]   NA   NA   NA   NA   NA
>> #[11,]   NA   NA   NA   NA   NA
>> #[12,]   NA   NA   NA   NA   NA
>> #[13,]   NA   NA   NA   NA   NA
>> #[14,]   NA   NA   NA   NA   NA
>> #[15,]   NA   NA   NA   NA   NA
>> #[16,]   NA   NA   NA   NA   NA
>> #[17,]   NA   NA   NA   NA   NA
>> #[18,]   NA   NA   NA   NA   NA
>> #[19,]   NA   NA   NA   NA   NA
>> #[20,]   NA   NA   NA   NA   NA
>> A.K.
>>
>>
>>
>> ----- Original Message -----
>> From: Anika Masters <anika.masters at gmail.com>
>> To: R help <r-help at r-project.org>
>> Cc:
>> Sent: Thursday, June 27, 2013 3:00 PM
>> Subject: [R] using "rollapply" to calculate a moving sum or running sum?
>>
>> #using "rollapply" to calculate a moving sum or running sum?
>>
>> #I am tryign to use rollapply to calcualte a moving sum? #I tried
>> rollapply and get the error message
>> #"Error in seq.default(start.at, NROW(data), by = by) :
>> #  wrong sign in 'by' argument"
>>
>> #example:
>>
>> mymatrix <- ( matrix(data=1:100, nrow=5, ncol=20) )
>> mymatrix_cumsum  <- ( matrix(data=NA, nrow=5, ncol=20) )
>> w=12
>> for(i in 1: (ncol(mymatrix)-w+1) ) {
>> mymatrix_cumsum[ , i]  <- apply(X=mymatrix[, i:(i+w-1)] , MARGIN=1,
>> FUN=sum, na.rm=T)
>> }
>>
>> #How might I use the "rollapply" function instead?
>>
>> rollapply(mymatrix, 12, sum)
>>
>> rollapply(data = mymatrix, width = 12, FUN=sum, by.column =T, fill =
>> NA, partial = FALSE, align = "left" )
>>

-- 
Enrico Schumann
Lucerne, Switzerland
http://enricoschumann.net



More information about the R-help mailing list