Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Consecutive/Rolling sums in a vector in R

Tags:

Suppose in R I have the following vector :

[1 2 3 10 20 30]

How do I perform an operation whereby at each index 3 consecutive elements are summed, resulting in the following vector :

[6 15 33 60]

where the first element = 1+2+3, the second element = 2+3+10 etc...? Thanks

like image 873
user2834313 Avatar asked Oct 05 '13 17:10

user2834313


2 Answers

What you have is a vector, not an array. You can use rollapply function from zoo package to get what you need.

> x <- c(1, 2, 3, 10, 20, 30)
> #library(zoo)
> rollapply(x, 3, sum)
[1]  6 15 33 60

Take a look at ?rollapply for further details on what rollapply does and how to use it.

like image 53
Jilber Urbina Avatar answered Sep 28 '22 04:09

Jilber Urbina


I put together a package for handling these kinds of 'roll'ing functions that offers functionality similar to zoo's rollapply, but with Rcpp on the backend. Check out RcppRoll on CRAN.

library(microbenchmark)
library(zoo)
library(RcppRoll)

x <- rnorm(1E5)

all.equal( m1 <- rollapply(x, 3, sum), m2 <- roll_sum(x, 3) )

## from flodel
rsum.cumsum <- function(x, n = 3L) {
  tail(cumsum(x) - cumsum(c(rep(0, n), head(x, -n))), -n + 1)
}

microbenchmark(
  unit="ms",
  times=10,
  rollapply(x, 3, sum),
  roll_sum(x, 3),
  rsum.cumsum(x, 3)
)

gives me

Unit: milliseconds
                 expr         min          lq      median         uq         max neval
 rollapply(x, 3, sum) 1056.646058 1068.867550 1076.550463 1113.71012 1131.230825    10
       roll_sum(x, 3)    0.405992    0.442928    0.457642    0.51770    0.574455    10
    rsum.cumsum(x, 3)    2.610119    2.821823    6.469593   11.33624   53.798711    10

You might find it useful if speed is a concern.

like image 25
Kevin Ushey Avatar answered Sep 28 '22 04:09

Kevin Ushey