Reputation: 219
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
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
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