ikemblem
ikemblem

Reputation: 333

Converting Nested For Loop with Rolling Function to apply

Currently, have an XTS variable with several columns and my goal is to apply a certain rolling function to each column of the dataset. The nested for loop approach that I am using below is very slow and I understand that apply statements may help speed up the process. I was wondering if anyone could guide me on the best way to convert the nested for loops to apply statements or just ways in which to speed up the code in general.

Head of part of the data set:

Data <-
structure(c(-0.003703704, 0.038104089, -0.000895255, -0.002389486, 
0.00988024, 0.00889416, 0.002514368, 0.020781082, 0.002457002, 
-0.023459384, 0.019361778, 0.004220893, -0.048253968, 0.105737158, 
0.04147813, -0.03070239, 0.039593605, 0.033774073, -0.002636625, 
0.020908435, -0.003766478, -0.002126654, 0.004972768, 0.005655042, 
-0.003175947, 0.013169074, -0.01572327, 0.003833866, 0.00466794, 
-0.004223865, 0.010963195, -0.004802479, -0.005292653, -0.003286385, 
0.011775789, 0.000310366, 0.002399232, 0.038774533, -0.014746544, 
-0.004209542, 0.039924847, -0.004968383, 0.029471545, -0.000987167, 
-0.005928854, -0.005964215, 0.007, -0.002979146, 0.005352645, 
0.002818666, 0, -0.00843223, 0.004724409, -0.005642633, -0.013913043, 
0.005291005, 0.026315789, 0.015384615, -0.03030303, 0.029513889, 
0.076259947, -0.017868145, -0.010037641, 0.002534854, -0.003792668, 
-0.021573604, 0.037435657, 0.00947226, -0.023235031, 0.005032022, 
-0.017296313, -0.004168597, 0.020424195, 0.056197075, 0.021137026, 
-0.017130621, -0.007262164, 0.00658376, -0.014313598, -0.027062706, 
0.05156038, 0.059354839, -0.018879415, 0.037243948, 0, 0.009724257, 
-0.00171504, -0.021540901, 0.014721772, -0.012777852), class = c("xts", 
"zoo"), .indexCLASS = "Date", tclass = "Date", .indexTZ = "UTC", tzone = "UTC",
index = structure(c(1073001600, 1073260800, 1073347200, 1073433600, 1073520000,
1073606400), tzone = "UTC", tclass = "Date"), .Dim = c(6L, 15L),
.Dimnames = list(NULL, c("WTI", "BRENT", "NATGAS", "GOLD", "SILVER", "ALUM",
"COPPER", "CORN", "SOY", "SUGAR", "WHEAT", "LHOG", "ARACOF", "COCOA", "COT")))

Nested For-Loop Code: adjFutData = Data set shown above, window = Rolling window size

test = function(adjFutData, window) {

  test = xts(matrix(data = NA,
                    nrow = nrow(adjFutData),
                    ncol = (ncol(adjFutData))),
             order.by = index(adjFutData))

  for (j in 1:ncol(adjFutData)){
    for (i in 1:nrow(adjFutData)){
      if (i>window){
        start = i - window
        end = i-1
        test[i,j] = log(prod(1+adjFutData[start:end,j]))
      }
    }
  }
  return(test)
}

Upvotes: 2

Views: 408

Answers (2)

G. Grothendieck
G. Grothendieck

Reputation: 269481

Try this:

rollapply(as.zoo(Data), list(-seq(3)), function(x) log(prod(1+x)), fill = NA)

This also works:

rollapplyr(Data, 4, function(x) log(prod(1+x[1:3])), fill = NA)

Upvotes: 1

Joshua Ulrich
Joshua Ulrich

Reputation: 176648

Use rollapply, which is in the zoo package:

r <- rollapplyr(Data, 3, function(s) log(prod(1+s)), by.column=TRUE)

Upvotes: 2

Related Questions