-3

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')
}
GSee
  • 48,880
  • 13
  • 125
  • 145
StatsViaCsh
  • 2,600
  • 10
  • 44
  • 63
  • 4
    You ask several questions here to know that we need a reproductible example to help you. For example simplifying your code just enough to reproduce the behavior and giving code to get the data through `tseries::get.hist.quote` and providing `symbs` object for example will be perfect. – dickoa Jul 28 '13 at 19:54
  • I'm not sure I understand everything that's going on in the code, but I think you probably want `importData[[sIdx]]` in both places in the first loop. (i.e. `[[` instead of `[`) You'll also probably be interested to know that your giant merge in the second loop could be replaced with `do.call(merge, monthlyPctChgs)`. However, I'm not sure it's doing what you think it is; it looks like your code is making the assumption that `NROW(symbs) == 12`. – GSee Jul 28 '13 at 20:22
  • I just provided symbs, I knew better... thx. – StatsViaCsh Jul 28 '13 at 20:38

1 Answers1

1

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

Community
  • 1
  • 1
dickoa
  • 18,217
  • 3
  • 36
  • 50
  • btw i did mention in my post the understanding that apply was far better form. – StatsViaCsh Jul 29 '13 at 02:54
  • @StatsViaCsh Yes you're right and I'll encourage you to perfect your understanding of *apply mechanism in R. You'll save a lot of time. – dickoa Jul 29 '13 at 03:24