Объединение большого списка объектов xts

У меня есть список объектов xts, которые являются взаимоисключающими днями. Я хотел бы merge список в один большой объект xts. Моя попытка сделать это была "

merged_reg_1_min_prices <- do.call(cbind, reg_1_min_prices)

Однако у этого, похоже, заканчивается память. reg_1_min_prices составляет 6000 дней с 1 минутой возвращения во взаимоисключающие дни, поэтому он не очень большой. Кто-нибудь знает, как обойти это?

Чтобы быть ясным: reg_1_min_prices содержит взаимоисключающие дни с 1 минутой цены в каждый день, и каждая запись в списке - это объект xts.

Ответ 1

Я использую стратегию Dominik в его ответе на этот вопрос

Я превратил его в функцию в мой qmao. Этот код также находится в ядре getSymbols.FI в FinancialInstrument пакет.

do.call.rbind <- function(lst) {
  while(length(lst) > 1) {
    idxlst <- seq(from=1, to=length(lst), by=2)
    lst <- lapply(idxlst, function(i) {
      if(i==length(lst)) { return(lst[[i]]) }
      return(rbind(lst[[i]], lst[[i+1]]))
    })
  }
  lst[[1]]
}

Если вы хотите rbind data.frames, @JoshuaUlrich предоставили элегантное решение здесь


Насколько я могу судить (не глядя очень внимательно), память не является проблемой ни с одним из трех предлагаемых решений (@JoshuaUlrich, @Alex и qmao:: do.call.rbind). Итак, скорость сводится...

library(xts)
l <- lapply(Sys.Date()-6000:1, function(x) {
    N=60*8;xts(rnorm(N),as.POSIXct(x)-seq(N*60,1,-60))})
GS <- do.call.rbind
JU <- function(x) Reduce(rbind, x)
Alex <- function(x) do.call(rbind, lapply(x, as.data.frame)) #returns data.frame, not xts

identical(GS(l), JU(l)) #TRUE

library(rbenchmark)
benchmark(GS(l), JU(l), Alex(l), replications=1)
     test replications elapsed relative user.self sys.self user.child sys.child
3 Alex(l)            1  89.575 109.9080    56.584   33.044          0         0
1   GS(l)            1   0.815   1.0000     0.599    0.216          0         0
2   JU(l)            1 209.783 257.4025   143.353   66.555          0         0

do.call.rbind явно выигрывает по скорости.

Ответ 2

Вы не хотите использовать merge, потому что это приведет к возврату объекта с 6000 столбцами с строкой для каждой строки в каждом элементе списка (2880 000 в моем примере). И большинство значений будет NA. cbind.xts просто вызывает merge.xts с несколькими значениями аргументов по умолчанию, поэтому вы также не хотите использовать их.

Мы знаем о проблеме с памятью, вызванной вызовом rbind.xts через do.call. У Джеффа есть более эффективный код, но это прототип, который не является общедоступным.

Альтернативой @GSee solution является использование Reduce. Это займет некоторое время, чтобы работать на моем ноутбуке, но память не является проблемой даже с 4 ГБ.

library(xts)
l <- lapply(Sys.Date()-6000:1, function(x) {
  N=60*8;xts(rnorm(N),as.POSIXct(x)-seq(N*60,1,-60))})
x <- Reduce(rbind, l)

Ответ 3

Вот как это сделать эффективно: конвертируйте каждый объект xts в data.frame и просто rbind их. Это почти не увеличивает использование памяти. При необходимости просто создайте новый xts объект из data.frame