10

I have a loop that extracts ~200 individual timeseries by making calls to an API.

The loop outputs the timeseries as xts objects (library(xts)) into the Global Environment with the suffix ".oc". So I have 200 xts objects of the form "ABC.oc", "ABD.oc" etc. Each object contains 1000 rows of data.

What I would like to do is write a loop (or use an appropriate function) that takes all the "*.oc" objects and merges them by column. IE would end up with:

Date           ABC.oc    ABD.oc -> 200 columns like this
2011-01-01      10         10
2011-01-02      20         20
2011-01-03      30         30
2011-01-04      40         40
2011-01-05      50         50

With a short list of timeseries, would just write:

m <- merge(ABC.oc,ABD.oc,all=FALSE)

But obviously this is not practical with 200 individual objects, so I'd like to write a loop to smash all these objects together like "merge" does.

Easy enough to access the variables for the loop via for i in length(ls(pattern="*.oc")){ but just cannot figure out the rest of the loop. I've tried cbind, but can't seem to get it right.

Any help much appreciated

n.e.w
  • 1,128
  • 10
  • 23

2 Answers2

17

This can be accomplished by getting a character vector of all the objects with names ending in .oc, putting them in a list, then calling merge via do.call.

# Make up some data
set.seed(21)
x.oc <- xts(rnorm(10), Sys.Date()-10:1)
y.oc <- xts(rnorm(10), Sys.Date()-10:1)
z.oc <- xts(rnorm(10), Sys.Date()-10:1)
x <- y <- z <- 1:10

objNames <- ls(pattern="*oc$")    # object names
objList <- lapply(objNames, get)  # list of objects
names(objList) <- objNames        # assign names to list
do.call(merge, objList)           # merge all objects in list

Using this method would be easier if you loaded the xts objects into a list (objList) as you received them from the API. Then you would only need do.call(merge, objList).

Joshua Ulrich
  • 173,410
  • 32
  • 338
  • 418
2

A loop like this should work. Always a good idea to initialise it first though.

library(xts)

m <- xts(matrix(vector(length=length(ls(pattern="*.oc")) * 
  nrow(get(ls(pattern="*.oc")[1]), ncol=nrow(get(ls(pattern="*.oc")[1])), 
  order.by=index(get(ls(pattern="*.oc")[1]))

for (i in 1:length(ls(pattern="*.oc"))) {
  m[, i]  <- get(ls(pattern="*.oc")[i])
}
wkmor1
  • 7,226
  • 3
  • 31
  • 23
  • This is great - will try it out. If I wanted to generalize the length from 1000 rows to an arbitrary / dynamic length, what would you suggest? – n.e.w Jun 16 '11 at 23:58
  • @n.e.w the edits I made will generalise both the number of objects and the number of rows they have – wkmor1 Jun 17 '11 at 01:23