ejemplo - fusionar una gran lista de objetos xts
html h2 h3 (3)
Aquí se muestra cómo hacer esto de manera eficiente: convierta cada objeto xts
a data.frame
y simplemente rbind
. Esto no aumenta el uso de memoria casi en absoluto. Si es necesario, simplemente crea un nuevo objeto xts
desde data.frame
Tengo una lista de objetos xts
que son días mutuamente excluyentes. Me gustaría merge
la lista en un gran objeto xts
. Mi intento de hacer esto fue para "
merged_reg_1_min_prices <- do.call(cbind, reg_1_min_prices)
Sin embargo, parece que se ha quedado sin memoria. reg_1_min_prices
es de 6.000 días de devoluciones de 1 minuto en días mutuamente exclusivos, por lo que no es muy grande. ¿Alguien sabe cómo evitar esto?
Para que quede claro: reg_1_min_prices
contiene días mutuamente excluyentes con precios de 1 minuto cada día y cada entrada en la lista es un objeto xts
.
No desea utilizar merge
porque eso devolvería un objeto de 6000 columnas con una fila para cada fila en cada elemento de lista (2,880,000 en mi ejemplo). Y la mayoría de los valores serán NA
. cbind.xts
simplemente llama a merge.xts
con algunos valores de argumento predeterminados, por lo que tampoco desea usarlo.
Somos conscientes del problema de memoria causado al llamar a rbind.xts
través de do.call
. Jeff tiene un código más eficiente, pero es un prototipo que no es público.
Una alternativa a la solución de @ GSee es usar Reduce
. Me lleva un tiempo ejecutarlo en mi computadora portátil, pero la memoria no es un problema, incluso con solo 4 GB.
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)
Uso la estrategia proporcionada por Dominik en su respuesta a esta pregunta
Lo he convertido en una función en mi paquete qmao . Este código también se encuentra en el núcleo de getSymbols.FI en el paquete 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]]
}
Si desea rbind
data.frames
, @JoshuaUlrich ha proporcionado una solución elegante aquí
Por lo que puedo decir (sin mirar muy de cerca) la memoria no es un problema con ninguna de las tres soluciones ofrecidas ( @ JoshuaUlrich''s , @ Alex''s y qmao :: do.call.rbind). Entonces, todo se reduce a la velocidad ...
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
claramente gana velocidad.