On Fri, 02 Aug 2013, Anika Masters <anika.mast...@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 <smartpink...@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.mast...@gmail.com> >> To: R help <r-help@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 ______________________________________________ R-help@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide http://www.R-project.org/posting-guide.html and provide commented, minimal, self-contained, reproducible code.