una - series de tiempo multivariadas en r
R: fusionar dos series de tiempo irregulares (4)
Tengo dos series de tiempo multivariable x e y, ambas cubren aproximadamente el mismo rango en el tiempo (una comienza dos años antes que la otra, pero termina en la misma fecha). Ambas series tienen observaciones faltantes en forma de columnas vacías junto a la columna de fecha, y también en el sentido de que una de las series tiene varias fechas que no se encuentran en la otra, y viceversa.
Me gustaría crear un marco de datos (o similar) con una columna que enumera todas las fechas encontradas en x OR y, sin fechas duplicadas. Para cada fecha (fila), me gustaría apilar horizontalmente las observaciones de x al lado de las observaciones de y, con NA llenando las celdas faltantes. Ejemplo:
>x
"1987-01-01" 7.1 NA 3
"1987-01-02" 5.2 5 2
"1987-01-06" 2.3 NA 9
>y
"1987-01-01" 55.3 66 45
"1987-01-03" 77.3 87 34
# result I would like
"1987-01-01" 7.1 NA 3 55.3 66 45
"1987-01-02" 5.2 5 2 NA NA NA
"1987-01-03" NA NA NA 77.3 87 34
"1987-01-06" 2.3 NA 9 NA NA NA
Lo que he intentado: con el paquete del zoológico, probé el método merge.zoo, pero parece que solo apilan las dos series una al lado de la otra, con las fechas (como números, por ejemplo, "1987-01-02" mostrado como 6210) de cada serie que aparece en dos columnas separadas.
Me he sentado durante horas sin llegar a ninguna parte, por lo que se agradece toda la ayuda.
EDITAR: algunos códigos incluidos a continuación según la sugerencia de Soumendra
atcoa <- read.csv(file = "ATCOA_full_adj.csv", header = TRUE)
atcob <- read.csv(file = "ATCOB_full_adj.csv", header = TRUE)
atcoa$date <- as.Date(atcoa$date)
atcob$date <- as.Date(atcob$date)
# only number of observations and the observations themselves differ
>str(atcoa)
''data.frame'': 6151 obs. of 8 variables:
$ date :Class ''Date'' num [1:6151] 6210 6213 6215 6216 6217 ...
$ max : num 4.31 4.33 4.38 4.18 4.13 4.05 4.08 4.05 4.08 4.1 ...
$ min : num 4.28 4.31 4.28 4.13 4.05 3.95 3.97 3.95 4 4.02 ...
$ close : num 4.31 4.33 4.31 4.15 4.1 3.97 4 3.97 4.08 4.02 ...
$ avg : num NA NA NA NA NA NA NA NA NA NA ...
$ tot.vol : int 877733 89724 889437 1927113 3050611 846525 1782774 1497998 2504466 5636999 ...
$ turnover : num 3762300 388900 3835900 8015900 12468100 ...
$ transactions: int 12 9 24 17 31 26 34 35 37 33 ...
>atcoa[1:1, ]
date a.max a.min a.close a.avg a.tot.vol a.turnover a.transactions
1 1987-01-02 4.31 4.28 4.31 NA 877733 3762300 12
# using timeSeries package
ts.atcoa <- timeSeries::as.timeSeries(atcoa, format = "%Y-%m-%d")
ts.atcob <- timeSeries::as.timeSeries(atcob, format = "%Y-%m-%d")
>str(ts.atcoa)
Time Series:
Name: object
Data Matrix:
Dimension: 6151 7
Column Names: a.max a.min a.close a.avg a.tot.vol a.turnover a.transactions
Row Names: 1970-01-01 01:43:30 ... 1970-01-01 04:12:35
Positions:
Start: 1970-01-01 01:43:30
End: 1970-01-01 04:12:35
With:
Format: %Y-%m-%d %H:%M:%S
FinCenter: GMT
Units: a.max a.min a.close a.avg a.tot.vol a.turnover a.transactions
Title: Time Series Object
Documentation: Wed Aug 17 13:00:50 2011
>ts.atcoa[1:1, ]
GMT
a.max a.min a.close a.avg a.tot.vol a.turnover a.transactions
1970-01-01 01:43:30 4.31 4.28 4.31 NA 877733 3762300 12
# The following will create an object of class "data frame" and mode "list", which contains observations for the days mutual for the two series
>ts.atco <- timeSeries::merge(atcoa, atcob) # produces same result as base::merge, apparently
>ts.atco[1:1, ]
date a.max a.min a.close a.avg a.tot.vol a.turnover a.transactions b.max b.min b.close b.avg b.tot.vol b.turnover b.transactions
1 1989-08-25 7.92 7.77 7.79 NA 269172 2119400 19 7.69 7.56 7.64 NA 81176693 593858000 12
EDITAR: problema resuelto por (utilizando el paquete zoo)
atcoa <- read.zoo(read.csv(file = "ATCOA_full_adj.csv", header = TRUE))
atcob <- read.zoo(read.csv(file = "ATCOB_full_adj.csv", header = TRUE))
names(atcoa) <- c("a.max", "a.min", "a.close",
"a.avg", "a.tot.vol", "a.turnover", "a.transactions")
names(atcob) <- c("b.max", "b.min", "b.close",
"b.avg", "b.tot.vol", "b.turnover", "b.transactions")
atco <- merge.zoo(atcoa, atcob)
Gracias por toda tu ayuda.
Aquí, encontré un enfoque más genérico de stat.ethz.ch
a <- ts(1:10, start=c(2014,6), frequency=12)
b <- ts(1:12, start=c(2015,1), frequency=12)
library(zoo)
m <- merge(a = as.zoo(a), b = as.zoo(b))
para recuperar un objeto ts:
as.ts(m)
Prueba esto:
Lines.x <- ''"1987-01-01" 7.1 NA 3
"1987-01-02" 5.2 5 2
"1987-01-06" 2.3 NA 9''
Lines.y <- ''"1987-01-01" 55.3 66 45
"1987-01-03" 77.3 87 34''
library(zoo)
# in reality x might be in a file and might be read via: x <- read.zoo("x.dat")
# ditto for y. See ?read.zoo and the zoo-read vignette if you need other args too
x <- read.zoo(text = Lines.x)
y <- read.zoo(text = Lines.y)
merge(x, y)
dando:
V2.x V3.x V4.x V2.y V3.y V4.y
1987-01-01 7.1 NA 3 55.3 66 45
1987-01-02 5.2 5 2 NA NA NA
1987-01-03 NA NA NA 77.3 87 34
1987-01-06 2.3 NA 9 NA NA NA
Puede crear un objeto timeSeries (biblioteca timeSeries) a partir de sus fechas, combinarlo (el comportamiento de combinación predeterminado de TimeSeries es diferente de zoo y xts y hace exactamente lo que solicita) y luego hacer que zoo / xts objetos se conviertan en el resultado en caso de que No quiero quedarme con timeSeries.
Una forma rápida de probar es la siguiente, asumiendo que tiene dos objetos zz1 y zz2 en el zoológico -
library(timeSeries)
as.zoo(merge(as.timeSeries(zz1), as.timeSeries(zz2)))
Compara la salida del comando anterior con
merge(zz1, zz2)
También puedes enlazar -
cbind(zz1, zz2)
siempre que no haya columnas compartidas con los mismos nombres. Incluso si dicha columna está allí, puedes elegir las columnas por las que te unirás y obtendrás un objeto de zoológico.
cbind(zz1[, 1:2], zz2[, 2:3]) #Assuming other columns are common
Qué tal esto:
## Generate unique sorted time values.
i <- sort(unique(c(index(x), index(y))))
## Empty data matrix.
v <- matrix(nrow=length(i), ncol=6, NA)
## Pull in data items.
v[match(index(x), i), 1:3] <- coredata(x)
v[match(index(y), i), 4:6] <- coredata(y)
## Build new zoo object.
d <- zoo(v, order.by=i)