En la siguiente
entrada se muestra como guardar múltiples gráficos en una lista, para posteriormente
representarlos de manera conjunta. Puntualmente, deseamos graficar el correlograma asociado a cada una de las series disponibles en una base de datos, para posteriormente representarlos en un panel conjunto de gráficos. Para ello se utiliza la base EuStockMarkets, una data disponible en el
ambiente base de R, siendo una serie de tiempo sobre cotizaciones de diversos índices
financieros.
library(purrr)
library(tseries)
library(dplyr)
library(ggplot2)
EuStockMarkets %>% head()
Time Series:
Start = c(1991, 130)
End = c(1991, 135)
Frequency = 260
DAX SMI CAC FTSE
1991.496 1628.75 1678.1 1772.8 2443.6
1991.500 1613.63 1688.5 1750.5 2460.2
1991.504 1606.51 1678.6 1718.0 2448.2
1991.508 1621.04 1684.1 1708.1 2470.4
1991.512 1618.16 1686.6 1723.1 2484.7
1991.515 1610.61 1671.6 1714.3 2466.8
Puntualmente,
queremos guardar un correlograma para cada una de las series. Como se tratan de
cotizaciones o precios de diversos índices, obtenemos las tasas de crecimiento
de cada columna para generar un correlograma de estas tasas de variaciones, lugar
de las cotizaciones (recuerde que será muy seguro que las cotizaciones no se
comporten como series estacionarias dado que tienen una clara tendencia. En caso
de dudas comparar gráficos de la serie en nivel y en variaciones relativas).
my_data <- EuStockMarkets %>%
as.tibble() %>%
mutate(
across(everything(),
~((./dplyr::lag(.)-1)*100),
.names= "tc_{.col}"
)) %>%
dplyr::select(starts_with("tc_")) %>%
na.omit()
my_data
# A tibble: 1,859 x 4
tc_DAX tc_SMI tc_CAC tc_FTSE
<dbl> <dbl> <dbl> <dbl>
1 -0.928 0.620 -1.26 0.679
2 -0.441 -0.586 -1.86 -0.488
3 0.904 0.328 -0.576 0.907
4 -0.178 0.148 0.878 0.579
5 -0.467 -0.889 -0.511 -0.720
6 1.25 0.676 1.18 0.855
7 0.578 1.23 1.32 0.824
8 -0.287 -0.358 -0.193 0.0837
9 0.637 1.11 0.0171 -0.522
10 0.118 0.437 0.314 1.41
# ... with 1,849 more rows
Una vez
tenemos las tasas de variaciones diarias, ahora convertimos cada fila en una
serie temporal (map_df); agregamos una columna para representar los rezagos (bacdf$lag);
y reorganizaos la base de datos (dplyr::select(lag, everything())). Note la
estructura en que queda representada la data. En caso de tener variables no numérica,
como fechas o nombres, o dummy representando eventos o temporadas, estas deben
omitirse de esta data que servirá de base para generar los gráficos.
bacdf <- map_df(my_data, function(ts) acf(ts, plot =
FALSE)$acf)
bacdf$lag <- 0:(nrow(bacdf) - 1)
bacdf <- bacdf %>% dplyr::select(lag, everything())
bacdf
# A tibble: 33 x 5
lag tc_DAX tc_SMI tc_CAC tc_FTSE
<int> <dbl[,1,1]> <dbl[,1,1]> <dbl[,1,1]> <dbl[,1,1]>
1 0 1 ... 1 ... 1 ... 1 ...
2 1 -0.000771 ... 0.0475 ... 0.0294 ... 0.0924 ...
3 2 -0.0265 ... -0.0203 ... 0.00330 ... -0.00811 ...
4 3 -0.0113 ... -0.0178 ... -0.0461 ... 0.00100 ...
5 4 0.000469 ... 0.00677 ... 0.00565 ... -0.0240 ...
6 5 -0.0321 ... -0.0459 ... -0.0313 ... -0.0302 ...
7 6 0.00196 ... -0.0288 ... 0.00812 ... -0.0524 ...
8 7 -0.0305 ... -0.00663 ... -0.0486 ... -0.0477 ...
9 8 -0.00909 ... 0.0260 ... -0.0315 ... -0.000642 ...
10 9 0.0229 ... 0.00554 ... 0.0240 ... 0.0278 ...
# ... with 23 more rows
Ahora
generamos tres argumentos: el nombre de la variable donde tenemos el rezago
(lag); el nombre de las variables a representar en mi base de datos y una lista
vacía donde guardaremos correlograma asociado a cada serie.
myaxis <- colnames(bacdf[1])
mynames <- colnames(bacdf[-1])
graficos <- list()
Posteriormente
usamos una secuencia for usando la función
seq_along(), note que en cada vuelta
del bucle va a llamar el nombre de la variable que estamos usando. Ya dentro
del bucle se usa ggplot para generar
el correlograma, siendo la única diferencia que la variable y se llama como mynames[[i]], de forma tal que este
indexado al valor de i, y por tanto se vaya modificando en cada serie. Estos se
van guardando en la posición (graficos[[i]])
del mismo nombre de la lista que hemos creado.
for (i in seq_along(mynames)) {
print(i)
g <- ggplot(bacdf, aes_string(x = myaxis, y = mynames[[i]])) +
geom_segment(mapping = aes(xend = lag, yend = 0)) +
geom_point() +
geom_hline(yintercept = c(significance_level, -significance_level), lty = 3, color = "blue") +
ggtitle(mynames[[i]]) +
theme_minimal() +
coord_cartesian(xlim = c(2, 35), ylim=c(-.1,0.1))
graficos[[i]] <- ggplotGrob(g)
}
Finalmente, generamos el gráfico.
grid.arrange(grobs=graficos, ncol=2)
library(tseries)
library(dplyr)
library(ggplot2)
Start = c(1991, 130)
End = c(1991, 135)
Frequency = 260
DAX SMI CAC FTSE
1991.496 1628.75 1678.1 1772.8 2443.6
1991.500 1613.63 1688.5 1750.5 2460.2
1991.504 1606.51 1678.6 1718.0 2448.2
1991.508 1621.04 1684.1 1708.1 2470.4
1991.512 1618.16 1686.6 1723.1 2484.7
1991.515 1610.61 1671.6 1714.3 2466.8
as.tibble() %>%
mutate(
across(everything(),
~((./dplyr::lag(.)-1)*100),
.names= "tc_{.col}"
)) %>%
dplyr::select(starts_with("tc_")) %>%
na.omit()
# A tibble: 1,859 x 4
tc_DAX tc_SMI tc_CAC tc_FTSE
<dbl> <dbl> <dbl> <dbl>
1 -0.928 0.620 -1.26 0.679
2 -0.441 -0.586 -1.86 -0.488
3 0.904 0.328 -0.576 0.907
4 -0.178 0.148 0.878 0.579
5 -0.467 -0.889 -0.511 -0.720
6 1.25 0.676 1.18 0.855
7 0.578 1.23 1.32 0.824
8 -0.287 -0.358 -0.193 0.0837
9 0.637 1.11 0.0171 -0.522
10 0.118 0.437 0.314 1.41
# ... with 1,849 more rows
bacdf$lag <- 0:(nrow(bacdf) - 1)
bacdf <- bacdf %>% dplyr::select(lag, everything())
# A tibble: 33 x 5
lag tc_DAX tc_SMI tc_CAC tc_FTSE
<int> <dbl[,1,1]> <dbl[,1,1]> <dbl[,1,1]> <dbl[,1,1]>
1 0 1 ... 1 ... 1 ... 1 ...
2 1 -0.000771 ... 0.0475 ... 0.0294 ... 0.0924 ...
3 2 -0.0265 ... -0.0203 ... 0.00330 ... -0.00811 ...
4 3 -0.0113 ... -0.0178 ... -0.0461 ... 0.00100 ...
5 4 0.000469 ... 0.00677 ... 0.00565 ... -0.0240 ...
6 5 -0.0321 ... -0.0459 ... -0.0313 ... -0.0302 ...
7 6 0.00196 ... -0.0288 ... 0.00812 ... -0.0524 ...
8 7 -0.0305 ... -0.00663 ... -0.0486 ... -0.0477 ...
9 8 -0.00909 ... 0.0260 ... -0.0315 ... -0.000642 ...
10 9 0.0229 ... 0.00554 ... 0.0240 ... 0.0278 ...
# ... with 23 more rows
mynames <- colnames(bacdf[-1])
graficos <- list()
print(i)
g <- ggplot(bacdf, aes_string(x = myaxis, y = mynames[[i]])) +
geom_segment(mapping = aes(xend = lag, yend = 0)) +
geom_point() +
geom_hline(yintercept = c(significance_level, -significance_level), lty = 3, color = "blue") +
ggtitle(mynames[[i]]) +
theme_minimal() +
coord_cartesian(xlim = c(2, 35), ylim=c(-.1,0.1))
graficos[[i]] <- ggplotGrob(g)
}
Agradecimientos y créditos:
el código base usado dentro del bucle para generar el grafico final se obtuvo
de la entrada Plotting
multiple ACF with ggplot disponible en stackoverflow.com.