Combinar datos del panel para obtener datos de panel equilibrados
merge panel-data (2)
Tengo varios marcos de datos en forma de panel de datos. Ahora quiero fusionar estos marcos de datos del panel en un panel de datos. Estos marcos de datos tienen en común y diferentes entre ellos. Ilustramos lo siguiente:
df1:
Month variable Beta1 Beta2 Beta3 Beta4 Beta5 Beta6
Jan-05 A 1 2 3 4 5 6
Feb-05 A 2 3 4 5 6 7
Mar-05 A 3 4 5 6 7 8
Apr-05 A 4 5 6 7 8 9
May-05 A 5 6 7 8 9 10
Jun-05 A 6 7 8 9 10 11
Jul-05 A 7 8 9 10 11 12
Aug-05 A 8 9 10 11 12 13
Sep-05 A 9 10 11 12 13 14
Oct-05 A 10 11 12 13 14 15
Nov-05 A 11 12 13 14 15 16
Dec-05 A 12 13 14 15 16 17
Jan-05 B 12 12 12 12 12 12
Feb-05 B 12 12 12 12 12 12
Mar-05 B 12 12 12 12 12 12
Apr-05 B 12 12 12 12 12 12
May-05 B 12 12 12 12 12 12
Jun-05 B 12 12 12 12 12 12
Jul-05 B 12 12 12 12 12 12
Aug-05 B 12 12 12 12 12 12
Sep-05 B 12 12 12 12 12 12
Oct-05 B 12 12 12 12 12 12
Nov-05 B 12 12 12 12 12 12
Dec-05 B 12 12 12 12 12 12
df2:
Month variable Beta1 Beta2 Beta3 Beta4 Beta5 Beta6
Jan-06 A 1 2 3 4 5 6
Feb-06 A 2 3 4 5 6 7
Mar-06 A 3 4 5 6 7 8
Apr-06 A 4 5 6 7 8 9
May-06 A 5 6 7 8 9 10
Jun-06 A 6 7 8 9 10 11
Jul-06 A 7 8 9 10 11 12
Aug-06 A 8 9 10 11 12 13
Sep-06 A 9 10 11 12 13 14
Oct-06 A 10 11 12 13 14 15
Nov-06 A 11 12 13 14 15 16
Dec-06 A 12 13 14 15 16 17
Jan-06 C 12 12 12 12 12 12
Feb-06 C 12 12 12 12 12 12
Mar-06 C 12 12 12 12 12 12
Apr-06 C 12 12 12 12 12 12
May-06 C 12 12 12 12 12 12
Jun-06 C 12 12 12 12 12 12
Jul-06 C 12 12 12 12 12 12
Aug-06 C 12 12 12 12 12 12
Sep-06 C 12 12 12 12 12 12
Oct-05 C 12 12 12 12 12 12
Nov-05 C 12 12 12 12 12 12
Dec-05 C 12 12 12 12 12 12
El resultado deseado es el siguiente, quiero fusionar los marcos de datos del panel de modo que cada variable esté organizada crónicamente y si los datos no pueden durante un año, entonces tienen NA bajo Beta1, Beta2, etc.
Month variable Beta1 Beta2 Beta3 Beta4 Beta5 Beta6
Jan-05 A 1 2 3 4 5 6
Feb-05 A 2 3 4 5 6 7
Mar-05 A 3 4 5 6 7 8
Apr-05 A 4 5 6 7 8 9
May-05 A 5 6 7 8 9 10
Jun-05 A 6 7 8 9 10 11
Jul-05 A 7 8 9 10 11 12
Aug-05 A 8 9 10 11 12 13
Sep-05 A 9 10 11 12 13 14
Oct-05 A 10 11 12 13 14 15
Nov-05 A 11 12 13 14 15 16
Dec-05 A 12 13 14 15 16 17
Jan-06 A 1 2 3 4 5 6
Feb-06 A 2 3 4 5 6 7
Mar-06 A 3 4 5 6 7 8
Apr-06 A 4 5 6 7 8 9
May-06 A 5 6 7 8 9 10
Jun-06 A 6 7 8 9 10 11
Jul-06 A 7 8 9 10 11 12
Aug-06 A 8 9 10 11 12 13
Sep-06 A 9 10 11 12 13 14
Oct-06 A 10 11 12 13 14 15
Nov-06 A 11 12 13 14 15 16
Dec-06 A 12 13 14 15 16 17
Jan-05 B 12 12 12 12 12 12
Feb-05 B 12 12 12 12 12 12
Mar-05 B 12 12 12 12 12 12
Apr-05 B 12 12 12 12 12 12
May-05 B 12 12 12 12 12 12
Jun-05 B 12 12 12 12 12 12
Jul-05 B 12 12 12 12 12 12
Aug-05 B 12 12 12 12 12 12
Sep-05 B 12 12 12 12 12 12
Oct-05 B 12 12 12 12 12 12
Nov-05 B 12 12 12 12 12 12
Dec-05 B 12 12 12 12 12 12
Jan-06 B NA NA NA NA NA NA
Feb-06 B NA NA NA NA NA NA
Mar-06 B NA NA NA NA NA NA
Apr-06 B NA NA NA NA NA NA
May-06 B NA NA NA NA NA NA
Jun-06 B NA NA NA NA NA NA
Jul-06 B NA NA NA NA NA NA
Aug-06 B NA NA NA NA NA NA
Sep-06 B NA NA NA NA NA NA
Oct-06 B NA NA NA NA NA NA
Nov-06 B NA NA NA NA NA NA
Dec-06 B NA NA NA NA NA NA
Jan-05 C NA NA NA NA NA NA
Feb-05 C NA NA NA NA NA NA
Mar-05 C NA NA NA NA NA NA
Apr-05 C NA NA NA NA NA NA
May-05 C NA NA NA NA NA NA
Jun-05 C NA NA NA NA NA NA
Jul-05 C NA NA NA NA NA NA
Aug-05 C NA NA NA NA NA NA
Sep-05 C NA NA NA NA NA NA
Oct-05 C NA NA NA NA NA NA
Nov-05 C NA NA NA NA NA NA
Dec-05 C NA NA NA NA NA NA
Jan-06 C 12 12 12 12 12 12
Feb-06 C 12 12 12 12 12 12
Mar-06 C 12 12 12 12 12 12
Apr-06 C 12 12 12 12 12 12
May-06 C 12 12 12 12 12 12
Jun-06 C 12 12 12 12 12 12
Jul-06 C 12 12 12 12 12 12
Aug-06 C 12 12 12 12 12 12
Sep-06 C 12 12 12 12 12 12
Oct-06 C 12 12 12 12 12 12
Nov-06 C 12 12 12 12 12 12
Dec-06 C 12 12 12 12 12 12
Como mencioné anteriormente, que varios marcos de datos y su fusión probablemente darían como resultado cientos de miles de filas, por lo que podría abordar los problemas de memoria y espacio. Realmente agradecería su ayuda.
Dos posibilidades alternativas de las cuales especialmente las altenativas data.table son interesantes cuando la velocidad y la memoria son un problema:
base R:
Vincula los marcos de datos en uno:
df3 <- rbind(df1,df2)
Cree un marco de datos de referencia con todas las combinaciones posibles de
Month
y
variable
con
expand.grid
:
ref <- expand.grid(Month = unique(df3$Month), variable = unique(df3$variable))
all.x=TRUE
con
all.x=TRUE
para asegurarse de que las combinaciones que faltan estén llenas de valores NA:
merge(ref, df3, by = c("Month", "variable"), all.x = TRUE)
O (gracias a @PierreLafortune):
merge(ref, df3, by=1:2, all.x = TRUE)
tabla de datos :
Vincula los marcos de datos en uno con ''rbindlist'' que devuelve un ''data.table'':
library(data.table)
DT <- rbindlist(list(df1,df2))
Únase con una referencia para asegurarse de que todas las combinaciones estén presentes y que las que faltan estén llenas de NA:
DT[CJ(Month, variable, unique = TRUE), on = c(Month="V1", variable="V2")]
Todo junto en una sola llamada:
DT <- rbindlist(list(df1,df2))[CJ(Month, variable, unique = TRUE), on = c(Month="V1", variable="V2")]
Una alternativa es envolver
rbindlist
en
setkey
y luego expandir con
CJ
(cross join):
DT <- setkey(rbindlist(list(df1,df2)), Month, variable)[CJ(Month, variable, unique = TRUE)]
Hay una función para eso.
Combina los marcos de datos con
rbind
.
Luego use
complete
.
Mirará a través de los grupos en
variable
y llenará cualquiera con valores faltantes:
library(tidyr)
df3 <- do.call(rbind.data.frame, list(df1, df2))
df3$Month <- as.character(df3$Month)
df4 <- complete(df3, Month, variable)
df4$Month <- as.yearmon(df4$Month, "%b %Y")
df5 <- df4[order(df4$variable,df4$Month),]
df5
# Source: local data frame [72 x 8]
#
# Month variable Beta1 Beta2 Beta3 Beta4 Beta5 Beta6
# (yrmn) (fctr) (int) (int) (int) (int) (int) (int)
# 1 Jan 2005 A 1 2 3 4 5 6
# 2 Feb 2005 A 2 3 4 5 6 7
# 3 Mar 2005 A 3 4 5 6 7 8
# 4 Apr 2005 A 4 5 6 7 8 9
# 5 May 2005 A 5 6 7 8 9 10
# 6 Jun 2005 A 6 7 8 9 10 11
# 7 Jul 2005 A 7 8 9 10 11 12
# 8 Aug 2005 A 8 9 10 11 12 13
# 9 Sep 2005 A 9 10 11 12 13 14
# 10 Oct 2005 A 10 11 12 13 14 15
# .. ... ... ... ... ... ... ... ...
Una implementación alternativa con dplyr y tidyr :
library(dplyr)
library(tidyr)
df3 <- bind_rows(df1, df2) %>%
complete(Month, variable)