Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the fastest way in R to calculate rolling max with a variable rolling window size?

Tags:

r

I have 2 numeric vectors, one stores values to calculate maximum from, another lengths of a rolling window to calculate those maximums on a rolling basis. Below is some sample code. Generally I'm trying to speed up the code inside system.time. Is there some ready function or vectorized way to do the same thing?

a <- rep(1:5,20000)
set.seed(123)
b <- rep(sample(1:50),2000)

system.time({
out <- vector(mode='numeric', length=NROW(a))
for(i in seq(a)) {
  if (i-b[i]>=0) out[i] <- max(a[(i-b[i]+1):i])
  else out[i] <- NA
}
})
like image 570
user1603038 Avatar asked Apr 26 '13 09:04

user1603038


People also ask

How to calculate a rolling average in R?

Calculating rolling averages To calculate a simple moving average (over 7 days), we can use the rollmean() function from the zoo package. This function takes a k , which is an 'integer width of the rolling window. The code below calculates a 3, 5, 7, 15, and 21-day rolling average for the deaths from COVID in the US.

What is a moving window in R?

Moving window analysis, sometimes referred to as focal analysis, is the process of calculating a value for a specific neighborhood of cells in a given raster. Typical functions calculated across the neighborhood are sum, mean, min, max, range, etc.

What is rolling window?

A Rolling window is expressed relative to the delivery date and automatically shifts forward with the passage of time. For example, a customer with a 5-year Rolling window who gets a delivery on May 4, 2015 would receive data covering the period from May 4, 2015 to May 4, 2020.


1 Answers

Managed to vectorize parts of it:

Original -

system.time({
  out <- vector(mode='numeric', length=NROW(a))
  for(i in seq(a)) {
    if (i-b[i]>=0) out[i] <- max(a[(i-b[i]+1):i])
    else out[i] <- NA
  }
})
## user  system elapsed 
## 0.64    0.00    0.64 

Slightly vectorized -

system.time({
  nr <- NROW(a)
  out <- rep(NA,nr)
  m <- 1:nr - b + 1
  n <- (1:nr)[m>0]

  for(i in n)
    out[i] <- max(a[m[i]:i])
})
## user  system elapsed 
## 0.39    0.00    0.39 
like image 182
Nishanth Avatar answered Oct 19 '22 23:10

Nishanth