Question

I'm trying to merge zoo classes within a loop, accumulating zoo series as new 'columns' with each iteration. I initialize an empty zoo() prior to running the loop. After my code completes, I get 'zoo series without observations' when I call str() on it. Yet, when I experiment with initializing an empty zoo, then merging it with itself and another instance with data, it works fine. The zoo in question below is 'monthlyReturns' in the 2nd loop. Btw I do know I'd be better served using the apply family. That will be next. What am I doing wrong?

library(tseries)
library(zoo)
symbs = c('XLF', 'XLE', 'XLU', 'SPY')
importData = vector('list', length(symbs))
cumInvestmentReturns = zoo()
monthlyReturns = zoo()

#Get monthly pricing data.
for (sIdx in 1:length(symbs)){
    #Import the data for each symbol into the list.
    importData[sIdx] = get.hist.quote(instrument= symbs[sIdx], start="2000-01-01", end="2013-07-15", 
          quote="AdjClose", provider="yahoo", origin="1970-01-01", compression="m", retclass="zoo")
    names(importData[sIdx]) = symbs[sIdx]
}

#Loop over length of lookback months (1-12) to check for performance of best etf in past period.
for (numbOfMonths in 1:12){
    #Calculate performances on each symbol, using the lookback length of variable numbOfMonths.
    monthlyPctChgs = lapply(importData, function(x) diff(x, lag =numbOfMonths) / lag(x, k=-numbOfMonths))
    names(monthlyPctChgs) = symbs

    #combine all ticker time series into one time series.
    tsPctChgs = merge(monthlyPctChgs[[1]], monthlyPctChgs[[2]], monthlyPctChgs[[3]], monthlyPctChgs[[4]], 
          monthlyPctChgs[[5]], monthlyPctChgs[[6]], monthlyPctChgs[[7]], monthlyPctChgs[[8]], 
          monthlyPctChgs[[9]], monthlyPctChgs[[10]], monthlyPctChgs[[11]], monthlyPctChgs[[12]])
    names(tsPctChgs) = symbs

    curBestLagPerfs <- rollapplyr(tsPctChgs, 2, function(x) x[2,which.max(x[1,])], by.column=FALSE)
    monthlyReturns = merge(monthlyReturns, curBestLagPerfs)
    #finalSet = finalSet[2:length(finalSet$SPY),] #Remove first value, since there is an na.

    lookbackReturns = cumprod(1+curBestLag) * 10000
    cumInvestmentReturns = merge(cumInvestmentReturns, lookbackReturns)
    #names(investmentsPaired) = c('SPY', 'ETFRotation')
}
Was it helpful?

Solution

If you want to avoid this kind of error and implement efficient code in R, you have to learn how to use function like lapply, apply and others *apply. There's an excellent post here

Here is my simplification of your code, not fully tested but it will give insight on how you can improve your code and correct some errors.

require(tseries)
require(zoo)
symbs <- c('XLF', 'XLE', 'XLU', 'SPY')

importData <- lapply(symbs, function(symb)
                     get.hist.quote(instrument= symb,
                                    start = "2000-01-01",
                                    end = "2013-07-15", 
                                    quote="AdjClose", provider = "yahoo",
                                    origin="1970-01-01", compression = "m",
                                    retclass="zoo"))

names(importData) <- symbs


monthlyPctChgs <- lapply(1:12, function(y)
                         lapply(importData,
                                function(x) diff(x, lag = y) / lag(x, lag = - y)))


tsPctChgs <- lapply(monthlyPctChgs, do.call, what = merge)


curBestLagPerfs <- lapply(tsPctChgs, function(y)
                          rollapplyr(y, 2,
                                     function(x) x[2,which.max(x[1,])],
                                     by.column=FALSE))

curBestLagPerfs <- do.call(merge, curBestLagPerfs)
names(curBestLagPerfs) <- month.abb
str(curBestLagPerfs)
## ‘zoo’ series from 2000-03-01 to 2013-06-03
##   Data: num [1:160, 1:12] 0.09156 0.00933 -0.00229 -0.06095 -0.01496 ...
##  - attr(*, "dimnames")=List of 2
##   ..$ : NULL
##   ..$ : chr [1:12] "Jan" "Feb" "Mar" "Apr" ...
##   Index:  Date[1:160], format: "2000-03-01" "2000-04-03" "2000-05-01" ...

Hope it will help

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top