Сохранять индекс xts при использовании rowSums на xts

Есть ли способ сохранить индекс объекта xts при передаче rowSums объекта xts?

В настоящее время я преобразую результат в объект xts, но это не так быстро, как могло бы быть, если бы rowSums мог просто вернуть то, что было передано.

xts(rowSums(abs(data)),index(data))

person theGreatKatzul    schedule 27.05.2017    source источник


Ответы (2)


Интересный вопрос. Давайте проигнорируем расчет abs, так как в большинстве случаев он не актуален только с ценами. Если вы беспокоитесь о производительности, вот набор сроков, которые следует учитывать для текущих предложений:

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) возвращает базовую числовую матрицу. Я думаю, что самая быстрая производительность, которую вы можете ожидать, дает rowSums(xx) для выполнения вычислений, которые можно считать «эталоном». Тогда возникает вопрос, как быстрее всего это сделать в объекте xts. Кажется, .xts(x = rowSums(sample.xts), .index(sample.xts)) дает достойную производительность.

person FXQuantTrader    schedule 28.05.2017
comment
Спасибо за быстрый и вдумчивый ответ Джош. - person theGreatKatzul; 30.05.2017
comment
@theGreatKatzul: Это ответ FXQuantTrader. Мой единственный вклад заключался в выравнивании заголовков в выводе микробенчмарка. - person Joshua Ulrich; 30.05.2017

Если ваше возражение состоит в том, чтобы разобрать и собрать компоненты ввода, тогда, если x является вашим объектом xts, попробуйте это. Он напрямую возвращает объект xts:

Reduce("+", as.list(x))
person G. Grothendieck    schedule 27.05.2017
comment
Спасибо за ответ. Моя главная забота заключалась в аккуратности, поскольку вызов уже существует внутри лямбда-функции. - person theGreatKatzul; 30.05.2017