3

Is there a way to preserve the index of an xts object when passing rowSums a xts object?

Currently I recast the result as an xts object, but this doesn't seem to be as fast as it could be if rowSums was able to simply return what it was passed.

xts(rowSums(abs(data)),index(data))
theGreatKatzul
  • 437
  • 1
  • 5
  • 16

2 Answers2

3

If your objection is having to pick apart and put together the components of the input then if x is your xts object then try this. It returns an xts object directly:

Reduce("+", as.list(x))
G. Grothendieck
  • 254,981
  • 17
  • 203
  • 341
3

Interesting question. Let's ignore the abs calculation, as it's not relevant a lot of the time with just prices. If your concern is performance, here is a set of timings to consider for the current suggestions:

library(microbenchmark)
sample.xts <- xts(order.by = as.POSIXct("2004-01-01 00:00:00") + 1:1e6, matrix(rnorm(1e6 *4), ncol = 4), dimnames = list(NULL, c("A", "B", "C", "D")))

# See how quickly rowSum works on just the underlying matrix of data in the timings below:
xx <- coredata(sample.xts)

microbenchmark(
    coredata(sample.xts),
    rowSums(xx),
    rowSums(sample.xts),
    rowSums(coredata(sample.xts)),
.xts(x = rowSums(sample.xts), .index(sample.xts)),
xts(rowSums(coredata(sample.xts)), index(sample.xts)),
xts(rowSums(sample.xts),index(sample.xts)), 
Reduce("+", as.list(sample.xts)), times = 100)

# Unit: milliseconds
#                                                  expr       min        lq      mean    median        uq       max neval
#                                  coredata(sample.xts)  2.558479  2.661242  6.884048  2.817607  6.356423 104.57993   100
#                                           rowSums(xx) 10.314719 10.824184 11.872108 11.289788 12.382614  18.39334   100
#                                   rowSums(sample.xts) 10.358009 10.887609 11.814267 11.335977 12.387085  17.16193   100
#                         rowSums(coredata(sample.xts)) 12.916714 13.839761 18.968731 15.950048 17.836838 113.78552   100
#     .xts(x = rowSums(sample.xts), .index(sample.xts)) 14.402382 15.764736 20.307027 17.808984 19.072600 114.24039   100
# xts(rowSums(coredata(sample.xts)), index(sample.xts)) 20.490542 24.183286 34.251031 25.566188 27.900599 125.93967   100
#           xts(rowSums(sample.xts), index(sample.xts)) 17.436137 19.087269 25.259143 21.923877 22.805013 119.60638   100
#                      Reduce("+", as.list(sample.xts)) 21.745574 26.075326 41.696152 27.669601 30.442397 136.38650   100

y = .xts(x = rowSums(sample.xts), .index(sample.xts))
y2 = xts(rowSums(sample.xts),index(sample.xts))
all.equal(y, y2)
#[1] TRUE

coredata(sample.xts) returns the underlying numeric matrix. I think the fastest performance you can expect is given by rowSums(xx) for doing the computation, which can be considered a "benchmark". The question is then, what's the quickest way to do it in an xts object. It seems .xts(x = rowSums(sample.xts), .index(sample.xts)) gives decent performance.

Joshua Ulrich
  • 173,410
  • 32
  • 338
  • 418
FXQuantTrader
  • 6,821
  • 3
  • 36
  • 67