sim235
sim235

Reputation: 219

Slow performance of nested loop in R

I have a xts series consisting of 250 observations and 584 columns. I am running a nested for loop on this series. This nested loops takes too much time. I have tried to create a reproducible example. On actual data set nested loop is taking too much time. Please suggest some efficient ways to do the same nested loop

library(PerformanceAnalytics)
library(xts)
library(zoo)
## dataset
bsereturn<-managers
##### calculating bse_lag
bse_lag<-head(bsereturn,-1)

## calculating bse forward
bse_forward<-tail(bsereturn,-1)

## defining look back and skip period
s=12
k=1
## Empty xts to store looping results
XSMOM = bse_lag
XSMOM[1:nrow(XSMOM),1:ncol(XSMOM)] <- NA
# Compute Momentum
system.time(for (i in 1:ncol(bse_lag)){
  
  for (t in (s + 1):nrow(bse_lag)){
    XSMOM[t,i] =  Return.cumulative(bse_lag[(t-s):(t-1-k),i])
    
  }
})

Upvotes: 3

Views: 484

Answers (2)

Joshua Ulrich
Joshua Ulrich

Reputation: 176648

The results in your example look weird to me. The return you have for 1997-01-31 is the cumulative return for 1996-01-31 through 1996-11-30. Why do you ignore the return from 1996-12-31?

Anyway, you use rollapply to get your answer. Your example runs ~4x faster for me than the single loop in Jerome's answer.

# this is what I would do
xsmom <- lag(rollapplyr(1 + bsereturn, 11, prod) - 1)
# this is what you have (lagged 2 periods)
xsmom2 <- lag(rollapplyr(1 + bsereturn, 11, prod) - 1, 2)

Upvotes: 3

J&#233;r&#244;me Richard
J&#233;r&#244;me Richard

Reputation: 50298

R loops are insanely slow. You can compute the cumulative return on multiple columns at the same time:

system.time(
    for (t in (s + 1):nrow(bse_lag)){
        XSMOM[t,1:ncol(bse_lag)] =  Return.cumulative(bse_lag[(t-s):(t-1-k),1:ncol(bse_lag)])
    }
)

This is about 5 times faster on my machine.

I think you can compute the cumulative return efficiently in an incremental way too (thus about s=12 times faster), but probably not directly in R.

Upvotes: 1

Related Questions