9

I would expect cbind.xts and do.call(cbind.xts) to perform with similar elapsed time. That was true for R2.11, R2.14.

For R2.15.2 and xts 0.8-8, the do.call(cbind.xts,...) variant performs drastically slower, which effectively breaks my previous codes.

As Josh Ulrich notes in a comment below, the xts package maintainers are aware of this problem. In the meantime, is there a convenient work around?

Reproducible example:

library(xts)

secs <- function (rows, from = as.character(Sys.time()), cols = 1, by = 1) 
{
    deltas <- seq(from = 0, by = by, length.out = rows)
    nacol <- matrix(data = NA, ncol = cols, nrow = rows)
    xts(x = nacol, order.by = strptime(from, format = "%Y-%m-%d %X") + 
        deltas)
}

n <- 20
d1 <- secs(rows=n*100,cols=n)
d2 <- secs(rows=n*100,cols=n)

system.time(cbind.xts(d1,d2))

versus

system.time(do.call(cbind.xts, list(d1,d2)))
Petr Matousu
  • 3,120
  • 1
  • 20
  • 32
  • Stackoverflow isn't the place to confirm behavior. You could edit your question to ask for a work-around. That said, we're aware of this and it has to do with `do.call` (and perhaps the unusual method dispatch of `cbind` and `rbind`); it is not specific to xts. – Joshua Ulrich Dec 17 '12 at 22:32
  • @JoshuaUlrich Well, who is aware of it? R-core team? Or xts team? What is the details of the problem? Please provide better information. – Petr Matousu Dec 17 '12 at 22:49
  • 1
    @PetrMatousu: Maybe you should learn who your package maintainers are. – IRTFM Dec 17 '12 at 22:51
  • Here's a work around to make `do.call(rbind.xts, ...)` faster. Maybe it'd help with `do.call(cbind.xts, ...)`, I dunno. http://stackoverflow.com/a/12029366/967840 – GSee Dec 17 '12 at 23:12
  • 1
    Can you provide a [reproducible example](http://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example)? – Joshua Ulrich Dec 17 '12 at 23:33
  • @JoshuaUlrich I removed his timong code in my edit, thinking it wasn't necessary. Feel free to roll back. – joran Dec 17 '12 at 23:41

1 Answers1

12

One work-around is to set quote=TRUE in do.call.

R> system.time(cb <- cbind.xts(d1,d2))
   user  system elapsed 
  0.004   0.000   0.004 
R> system.time(dc <- do.call(cbind.xts, list(d1,d2), quote=TRUE))
   user  system elapsed 
  0.000   0.004   0.004 
R> identical(cb,dc)
[1] TRUE

The slowness is caused by do.call evaluating the arguments before evaluating the function call by default, which causes the call to be much larger. For example, compare these two calls:

call("cbind", d1, d2)                # huge
call("cbind", quote(d1), quote(d2))  # dainty
Joshua Ulrich
  • 173,410
  • 32
  • 338
  • 418