packages <- c("readxl","dplyr", "ggplot2", "plotly", "tseries", "forecast","timetk", "scales")
for (pkg in packages) {
library(pkg, character.only = TRUE)
}
##
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
##
## filter, lag
## The following objects are masked from 'package:base':
##
## intersect, setdiff, setequal, union
##
## Attaching package: 'plotly'
## The following object is masked from 'package:ggplot2':
##
## last_plot
## The following object is masked from 'package:stats':
##
## filter
## The following object is masked from 'package:graphics':
##
## layout
## Registered S3 method overwritten by 'quantmod':
## method from
## as.zoo.data.frame zoo
Instalar/Cargar librerias necesarias para el análisis
data_col <- read_excel("C:\\Users\\soyso\\OneDrive\\Documentos\\AA_Viendo\\Econometría\\Precios_GLD.xlsx",col_types = c("date", "numeric"))
## Warning: Coercing text to numeric in B2 / R2C2: '109.43'
## Warning: Coercing text to numeric in B3 / R3C2: '108.95'
## Warning: Coercing text to numeric in B4 / R4C2: '115.36'
## Warning: Coercing text to numeric in B5 / R5C2: '118.88'
## Warning: Coercing text to numeric in B6 / R6C2: '121.68'
## Warning: Coercing text to numeric in B7 / R7C2: '115.49'
## Warning: Coercing text to numeric in B8 / R8C2: '122.08'
## Warning: Coercing text to numeric in B9 / R9C2: '127.91'
## Warning: Coercing text to numeric in B10 / R10C2: '132.62'
## Warning: Coercing text to numeric in B11 / R11C2: '135.42'
## Warning: Coercing text to numeric in B12 / R12C2: '138.72'
## Warning: Coercing text to numeric in B13 / R13C2: '129.87'
## Warning: Coercing text to numeric in B14 / R14C2: '137.66'
## Warning: Coercing text to numeric in B15 / R15C2: '139.86'
## Warning: Coercing text to numeric in B16 / R16C2: '152.37'
## Warning: Coercing text to numeric in B17 / R17C2: '149.64'
## Warning: Coercing text to numeric in B18 / R18C2: '146.00'
## Warning: Coercing text to numeric in B19 / R19C2: '158.29'
## Warning: Coercing text to numeric in B20 / R20C2: '177.72'
## Warning: Coercing text to numeric in B21 / R21C2: '158.06'
## Warning: Coercing text to numeric in B22 / R22C2: '167.34'
## Warning: Coercing text to numeric in B23 / R23C2: '170.13'
## Warning: Coercing text to numeric in B24 / R24C2: '151.99'
## Warning: Coercing text to numeric in B25 / R25C2: '169.31'
## Warning: Coercing text to numeric in B26 / R26C2: '164.29'
## Warning: Coercing text to numeric in B27 / R27C2: '162.12'
## Warning: Coercing text to numeric in B28 / R28C2: '161.88'
## Warning: Coercing text to numeric in B29 / R29C2: '151.62'
## Warning: Coercing text to numeric in B30 / R30C2: '155.19'
## Warning: Coercing text to numeric in B31 / R31C2: '156.49'
## Warning: Coercing text to numeric in B32 / R32C2: '164.22'
## Warning: Coercing text to numeric in B33 / R33C2: '171.89'
## Warning: Coercing text to numeric in B34 / R34C2: '166.83'
## Warning: Coercing text to numeric in B35 / R35C2: '166.05'
## Warning: Coercing text to numeric in B36 / R36C2: '162.02'
## Warning: Coercing text to numeric in B37 / R37C2: '161.20'
## Warning: Coercing text to numeric in B38 / R38C2: '153.00'
## Warning: Coercing text to numeric in B39 / R39C2: '154.47'
## Warning: Coercing text to numeric in B40 / R40C2: '142.77'
## Warning: Coercing text to numeric in B41 / R41C2: '133.92'
## Warning: Coercing text to numeric in B42 / R42C2: '119.11'
## Warning: Coercing text to numeric in B43 / R43C2: '127.96'
## Warning: Coercing text to numeric in B44 / R44C2: '134.62'
## Warning: Coercing text to numeric in B45 / R45C2: '128.18'
## Warning: Coercing text to numeric in B46 / R46C2: '127.74'
## Warning: Coercing text to numeric in B47 / R47C2: '120.70'
## Warning: Coercing text to numeric in B48 / R48C2: '116.12'
## Warning: Coercing text to numeric in B49 / R49C2: '120.09'
## Warning: Coercing text to numeric in B50 / R50C2: '127.62'
## Warning: Coercing text to numeric in B51 / R51C2: '123.61'
## Warning: Coercing text to numeric in B52 / R52C2: '124.22'
## Warning: Coercing text to numeric in B53 / R53C2: '120.43'
## Warning: Coercing text to numeric in B54 / R54C2: '128.04'
## Warning: Coercing text to numeric in B55 / R55C2: '123.39'
## Warning: Coercing text to numeric in B56 / R56C2: '123.86'
## Warning: Coercing text to numeric in B57 / R57C2: '116.21'
## Warning: Coercing text to numeric in B58 / R58C2: '112.66'
## Warning: Coercing text to numeric in B59 / R59C2: '112.11'
## Warning: Coercing text to numeric in B60 / R60C2: '113.58'
## Warning: Coercing text to numeric in B61 / R61C2: '123.45'
## Warning: Coercing text to numeric in B62 / R62C2: '116.16'
## Warning: Coercing text to numeric in B63 / R63C2: '113.66'
## Warning: Coercing text to numeric in B64 / R64C2: '113.47'
## Warning: Coercing text to numeric in B65 / R65C2: '114.10'
## Warning: Coercing text to numeric in B66 / R66C2: '112.37'
## Warning: Coercing text to numeric in B67 / R67C2: '104.93'
## Warning: Coercing text to numeric in B68 / R68C2: '108.82'
## Warning: Coercing text to numeric in B69 / R69C2: '106.86'
## Warning: Coercing text to numeric in B70 / R70C2: '109.30'
## Warning: Coercing text to numeric in B71 / R71C2: '101.92'
## Warning: Coercing text to numeric in B72 / R72C2: '101.46'
## Warning: Coercing text to numeric in B73 / R73C2: '106.95'
## Warning: Coercing text to numeric in B74 / R74C2: '118.64'
## Warning: Coercing text to numeric in B75 / R75C2: '117.64'
## Warning: Coercing text to numeric in B76 / R76C2: '123.65'
## Warning: Coercing text to numeric in B77 / R77C2: '116.06'
## Warning: Coercing text to numeric in B78 / R78C2: '126.47'
## Warning: Coercing text to numeric in B79 / R79C2: '128.98'
## Warning: Coercing text to numeric in B80 / R80C2: '124.78'
## Warning: Coercing text to numeric in B81 / R81C2: '125.64'
## Warning: Coercing text to numeric in B82 / R82C2: '121.94'
## Warning: Coercing text to numeric in B83 / R83C2: '111.75'
## Warning: Coercing text to numeric in B84 / R84C2: '109.61'
## Warning: Coercing text to numeric in B85 / R85C2: '115.55'
## Warning: Coercing text to numeric in B86 / R86C2: '119.23'
## Warning: Coercing text to numeric in B87 / R87C2: '118.72'
## Warning: Coercing text to numeric in B88 / R88C2: '120.77'
## Warning: Coercing text to numeric in B89 / R89C2: '120.62'
## Warning: Coercing text to numeric in B90 / R90C2: '118.02'
## Warning: Coercing text to numeric in B91 / R91C2: '120.75'
## Warning: Coercing text to numeric in B92 / R92C2: '125.82'
## Warning: Coercing text to numeric in B93 / R93C2: '121.58'
## Warning: Coercing text to numeric in B94 / R94C2: '120.67'
## Warning: Coercing text to numeric in B95 / R95C2: '121.10'
## Warning: Coercing text to numeric in B96 / R96C2: '123.65'
## Warning: Coercing text to numeric in B97 / R97C2: '127.65'
## Warning: Coercing text to numeric in B98 / R98C2: '125.00'
## Warning: Coercing text to numeric in B99 / R99C2: '125.79'
## Warning: Coercing text to numeric in B100 / R100C2: '124.59'
## Warning: Coercing text to numeric in B101 / R101C2: '123.10'
## Warning: Coercing text to numeric in B102 / R102C2: '118.65'
## Warning: Coercing text to numeric in B103 / R103C2: '115.99'
## Warning: Coercing text to numeric in B104 / R104C2: '113.51'
## Warning: Coercing text to numeric in B105 / R105C2: '112.76'
## Warning: Coercing text to numeric in B106 / R106C2: '115.15'
## Warning: Coercing text to numeric in B107 / R107C2: '115.54'
## Warning: Coercing text to numeric in B108 / R108C2: '121.25'
## Warning: Coercing text to numeric in B109 / R109C2: '124.75'
## Warning: Coercing text to numeric in B110 / R110C2: '123.99'
## Warning: Coercing text to numeric in B111 / R111C2: '122.01'
## Warning: Coercing text to numeric in B112 / R112C2: '121.20'
## Warning: Coercing text to numeric in B113 / R113C2: '123.33'
## Warning: Coercing text to numeric in B114 / R114C2: '133.20'
## Warning: Coercing text to numeric in B115 / R115C2: '133.21'
## Warning: Coercing text to numeric in B116 / R116C2: '143.75'
## Warning: Coercing text to numeric in B117 / R117C2: '138.87'
## Warning: Coercing text to numeric in B118 / R118C2: '142.43'
## Warning: Coercing text to numeric in B119 / R119C2: '137.86'
## Warning: Coercing text to numeric in B120 / R120C2: '142.90'
## Warning: Coercing text to numeric in B121 / R121C2: '149.33'
## Warning: Coercing text to numeric in B122 / R122C2: '148.38'
## Warning: Coercing text to numeric in B123 / R123C2: '148.05'
## Warning: Coercing text to numeric in B124 / R124C2: '158.80'
## Warning: Coercing text to numeric in B125 / R125C2: '162.91'
## Warning: Coercing text to numeric in B126 / R126C2: '167.37'
## Warning: Coercing text to numeric in B127 / R127C2: '185.43'
## Warning: Coercing text to numeric in B128 / R128C2: '184.83'
## Warning: Coercing text to numeric in B129 / R129C2: '177.12'
## Warning: Coercing text to numeric in B130 / R130C2: '176.20'
## Warning: Coercing text to numeric in B131 / R131C2: '166.67'
## Warning: Coercing text to numeric in B132 / R132C2: '178.36'
## Warning: Coercing text to numeric in B133 / R133C2: '172.61'
## Warning: Coercing text to numeric in B134 / R134C2: '161.81'
## Warning: Coercing text to numeric in B135 / R135C2: '159.96'
## Warning: Coercing text to numeric in B136 / R136C2: '165.66'
## Warning: Coercing text to numeric in B137 / R137C2: '178.38'
## Warning: Coercing text to numeric in B138 / R138C2: '165.63'
## Warning: Coercing text to numeric in B139 / R139C2: '169.82'
## Warning: Coercing text to numeric in B140 / R140C2: '169.69'
## Warning: Coercing text to numeric in B141 / R141C2: '164.22'
## Warning: Coercing text to numeric in B142 / R142C2: '166.65'
## Warning: Coercing text to numeric in B143 / R143C2: '165.50'
## Warning: Coercing text to numeric in B144 / R144C2: '170.96'
## Warning: Coercing text to numeric in B145 / R145C2: '168.09'
## Warning: Coercing text to numeric in B146 / R146C2: '178.38'
## Warning: Coercing text to numeric in B147 / R147C2: '180.65'
## Warning: Coercing text to numeric in B148 / R148C2: '176.91'
## Warning: Coercing text to numeric in B149 / R149C2: '171.14'
## Warning: Coercing text to numeric in B150 / R150C2: '168.46'
## Warning: Coercing text to numeric in B151 / R151C2: '164.10'
## Warning: Coercing text to numeric in B152 / R152C2: '159.27'
## Warning: Coercing text to numeric in B153 / R153C2: '154.67'
## Warning: Coercing text to numeric in B154 / R154C2: '151.91'
## Warning: Coercing text to numeric in B155 / R155C2: '164.81'
## Warning: Coercing text to numeric in B156 / R156C2: '169.64'
## Warning: Coercing text to numeric in B157 / R157C2: '179.41'
## Warning: Coercing text to numeric in B158 / R158C2: '169.78'
## Warning: Coercing text to numeric in B159 / R159C2: '183.22'
## Warning: Coercing text to numeric in B160 / R160C2: '184.80'
## Warning: Coercing text to numeric in B161 / R161C2: '182.32'
## Warning: Coercing text to numeric in B162 / R162C2: '178.27'
## Warning: Coercing text to numeric in B163 / R163C2: '182.35'
## Warning: Coercing text to numeric in B164 / R164C2: '180.02'
## Warning: Coercing text to numeric in B165 / R165C2: '171.45'
## Warning: Coercing text to numeric in B166 / R166C2: '184.09'
## Warning: Coercing text to numeric in B167 / R167C2: '188.75'
## Warning: Coercing text to numeric in B168 / R168C2: '191.17'
## Warning: Coercing text to numeric in B169 / R169C2: '188.45'
## Warning: Coercing text to numeric in B170 / R170C2: '189.31'
## Warning: Coercing text to numeric in B171 / R171C2: '205.72'
## Warning: Coercing text to numeric in B172 / R172C2: '211.87'
## Warning: Coercing text to numeric in B173 / R173C2: '215.30'
## Warning: Coercing text to numeric in B174 / R174C2: '215.01'
## Warning: Coercing text to numeric in B175 / R175C2: '226.55'
## Warning: Coercing text to numeric in B176 / R176C2: '231.29'
## Warning: Coercing text to numeric in B177 / R177C2: '243.06'
## Warning: Coercing text to numeric in B178 / R178C2: '253.51'
## Warning: Coercing text to numeric in B179 / R179C2: '245.59'
## Warning: Coercing text to numeric in B180 / R180C2: '242.13'
## Warning: Coercing text to numeric in B181 / R181C2: '258.56'
## Warning: Coercing text to numeric in B182 / R182C2: '263.27'
## Warning: Coercing text to numeric in B183 / R183C2: '275.24'
print(data_col)
## # A tibble: 182 × 2
## Fecha Precios
## <dttm> <dbl>
## 1 2010-02-01 00:00:00 109.
## 2 2010-03-01 00:00:00 109.
## 3 2010-04-01 00:00:00 115.
## 4 2010-05-01 00:00:00 119.
## 5 2010-06-01 00:00:00 122.
## 6 2010-07-01 00:00:00 115.
## 7 2010-08-01 00:00:00 122.
## 8 2010-09-01 00:00:00 128.
## 9 2010-10-01 00:00:00 133.
## 10 2010-11-01 00:00:00 135.
## # ℹ 172 more rows
PASO INDISPENSABLE: Declarar la (s) variable (s) como serie (s) temporal (es):
Variable
# Convertir/declarar variable 1=ENER en serie de tiempo mensual
variable1_ts <- ts(data_col$Precios, start = c(2010, 2), frequency = 12)
Muchas series de tiempo son una combinación de varias influencias. Es por eso que, separar la tendencia, la estacionalidad y los componentes aleatorios permite entender mejor qué está impulsando los cambios en la serie.
Si analizamos la creación de microempresas en Cali, podríamos querer saber si el crecimiento se debe a una tendencia real o a fluctuaciones estacionales.
Los modelos de pronóstico funcionan mejor cuando las señales subyacentes están bien definidas. Por ejemplo, si eliminamos la estacionalidad de una serie financiera, los modelos predictivos pueden enfocarse en la tendencia real y reducir errores. *Detectar cambios inesperados en la serie es más fácil cuando se eliminan componentes predecibles. Ejemplo: Si hay una caída abrupta en la variable podemos verificar si es una anomalía (ruido) o un cambio estructural en la economía.
En conclusión, la descomposición de series de tiempo permite comprender mejor los datos, mejorar predicciones y tomar decisiones más estratégicas. Es una herramienta clave en la analítica de negocios, especialmente en entornos donde las fluctuaciones en los datos pueden afectar inversiones, políticas económicas y estrategias empresariales.
Gráfico inicial de la variable 1 en niveles -Original
# Convertir la serie temporal a un vector numérico para lograr graficar con ggplot2
data_col$variable1 <- as.numeric(variable1_ts)
# Crear el gráfico
grafico_serie <- ggplot(data_col, aes(x = seq.Date(from = as.Date("2012-01-01"), by = "month", length.out = nrow(data_col)),
y = variable1)) +
geom_line(color = "grey", linewidth = 0.4) + # Cambiado 'size' por 'linewidth'
geom_point(color = "black", size = 0.1) +
ggtitle("Variable 1: Serie original") +
xlab("Tiempo") +
ylab("Unidad Variable 1") +
theme_minimal()
ggplotly(grafico_serie)
El oro ha sido considerado tradicionalmente como un activo refugio en tiempos de incertidumbre y como cobertura de inversiones. El gráfico de su serie de tiempo para los últimos quince años (2010-2025) evidencia esta realidad.
Al comienzo del periodo estudiado, la economía mundial estaba en los años posteriores a la crisis financiera mundial, periodo de mucha incertidumbre y desconfianza en los sistemas financiero tradicionales. Posterior a este periodo, las economías se fueron recuperando y la confianza se fue recuperando, con lo que los fondos salieron del activo refugio y probablemente se fueron a otras inversiones tradicionales. Otra vez tuvo un repunte después de la pandemia de la mano de la política monetaria expansiva que iniciaron los gobiernos. En los últimos años también se ha visto un sensación de incertidumbre en los mercados y una reducción de las tasas de intereses por muchos bancos centrales, lo cuál debilita las monedas y es un impulso a los refugios de la inflación, como el oro.
Extracción señales variable 1
# Cargar librerías necesarias
library(ggplot2)
library(plotly)
# Descomposición de la serie temporal
stl_decomp_var1 <- stl(variable1_ts, s.window = "periodic")
# Convertir la descomposición a un data frame para graficar con ggplot2
stl_df_var1 <- data.frame(
Time = rep(time(variable1_ts), 4), # Tiempo repetido para cada componente (son 4 componentes)
Value = c(stl_decomp_var1$time.series[, "seasonal"],
stl_decomp_var1$time.series[, "trend"],
stl_decomp_var1$time.series[, "remainder"],
variable1_ts),
Component = rep(c("Estacional", "Tendencia", "Residuo", "Serie Original"), each = length(variable1_ts))
)
# Crear gráfico con ggplot2
p <- ggplot(stl_df_var1, aes(x = Time, y = Value, color = Component)) +
geom_line() +
facet_wrap(~Component, scales = "free_y", ncol = 1) +
theme_minimal() +
labs(title = "Descomposición temporal de la variable 1",
x = "Tiempo",
y = "Valor")
# Convertir a gráfico interactivo con plotly
ggplotly(p)
Después de la descomposición temporal de cada variable, se extrae la variable ajustada por estacionalidad para graficarla junto con la serie original:
Se crea la variable1 ajustada por estacionalidad
# Extraer los componentes de la descomposición
variable1_sa <- variable1_ts - stl_decomp_var1$time.series[, "seasonal"]
Ahora si se puede graficar las series originales versus la ajustada por estacionalidad
Gráfico serie original VS ajustada Variable 1
# Crear vector de fechas correctamente alineado con la serie
fechas_var1 <- seq.Date(from = as.Date("2012-01-01"), by = "month", length.out = length(variable1_ts))
# Gráfico mejorado con fechas en el eje X
grafico_ajustada_var1 <- ggplot() +
geom_line(aes(x = fechas_var1, y = variable1_ts), color = "grey", size = 0.5, linetype = "solid", name = "Serie Original") +
geom_line(aes(x = fechas_var1, y = variable1_sa), color = "black", size = 0.6, linetype = "solid", name = "Serie Ajustada") +
ggtitle("Variable 1:Serie Original vs Serie Ajustada por Estacionalidad") +
xlab("Tiempo") +
ylab("Unidad de medida variable 1") +
theme_minimal() +
theme(axis.text.x = element_text(angle = 45, hjust = 1)) # Rotar etiquetas para mejor visualización
## Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
## ℹ Please use `linewidth` instead.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.
## Warning in geom_line(aes(x = fechas_var1, y = variable1_ts), color = "grey", :
## Ignoring unknown parameters: `name`
## Warning in geom_line(aes(x = fechas_var1, y = variable1_sa), color = "black", :
## Ignoring unknown parameters: `name`
# Convertir a gráfico interactivo
ggplotly(grafico_ajustada_var1)
## Don't know how to automatically pick scale for object of type <ts>. Defaulting
## to continuous.
Se observa que el precio de este ETF, no tiene practicamente ningún componente estacional, por lo tanto no hay situaciones anuales recurrentes que influyan en su comportamiento.
Ahora graficamos serie original vs tendencia
La extracción de la tendencia permite centrarse en los cambios estructurales de la serie.
Analizar la tendencia ayuda a prever escenarios futuros y anticipar posibles crisis o oportunidades en el sector o variable de análisis
Primero se debe obtener la tendencia de cada variable y luego graficarla
Tendencia Variable 1
# Convertir la serie a un vector numérico
variable1_vec <- as.numeric(variable1_ts)
tendencia_var1 <- as.numeric(stl_decomp_var1$time.series[, "trend"])
# Asegurar que 'fechas' tenga la misma longitud
fechas <- seq.Date(from = as.Date("2012-01-01"), by = "month", length.out = length(variable1_ts))
# Gráfico interactivo de la serie original vs tendencia
grafico_tendencia_var1 <- ggplot() +
geom_line(aes(x = fechas, y = variable1_vec, color = "Serie Original"), size = 0.7, linetype = "solid") +
geom_line(aes(x = fechas, y = tendencia_var1, color = "Tendencia"), size = 0.8, linetype = "solid") +
scale_color_manual(values = c("Serie Original" = "grey", "Tendencia" = "black")) +
ggtitle("Variable 1: Serie Original vs Tendencia") +
xlab("Tiempo") +
ylab("Unidad de medida Variable 1") +
theme_minimal() +
theme(axis.text.x = element_text(angle = 45, hjust = 1)) # Rotar etiquetas del eje X
# Convertir a gráfico interactivo con plotly
ggplotly(grafico_tendencia_var1)
Ahora calculamos la tasa de crecimiento de la serie original vs tendencia:
Tasa de crecimiento de la serie de tendencia y original para la variable 1
#Cálculo de la tasa de crecimiento anual correctamente alineada
tasa_crecimiento_var1 <- (variable1_ts[(13:length(variable1_ts))] / variable1_ts[1:(length(variable1_ts) - 12)] - 1) * 100
tasa_tendencia_var1 <- (tendencia_var1[(13:length(tendencia_var1))] / tendencia_var1[1:(length(tendencia_var1) - 12)] - 1) * 100
# Crear vector de fechas corregido, es decir que inicie desde enero 2013
fechas_corregidas_var1 <- seq(from = as.Date("2013-01-01"), by = "month", length.out = length(tasa_crecimiento_var1))
Gráfico variable original y tendencia variable 1: tasa de crecimiento anual
# Gráfico de la tasa de crecimiento anual variable 1
grafico_crecimiento_var1 <- ggplot() +
geom_line(aes(x = fechas_corregidas_var1, y = tasa_crecimiento_var1), color = "grey", size = 0.7) +
geom_line(aes(x = fechas_corregidas_var1, y = tasa_tendencia_var1), color = "black", size = 0.8, linetype = "dashed") +
ggtitle("Variable1: Tasa de crecimiento anual % de la serie Original y la tendencia") +
xlab("Tiempo") +
ylab("% de Crecimiento Anual") +
theme_minimal()
# Convertir a gráfico interactivo
ggplotly(grafico_crecimiento_var1)
Analizar la tasa de crecimiento anual ayuda a detectar cambios en el entorno económico que afectan el sector. Se pueden prever crisis o períodos de auge y prepararse para ellos.