1) Modelo del PIB a precios constantes

library(readxl)
PIB_a_precios_corrientes_trimestral <- read_excel("C:/Users/MINEDUCYT/Downloads/PIB a precios corrientes  trimestral.xls")
View(PIB_a_precios_corrientes_trimestral)

1.1 Calcular YT

library(readxl)
library(forecast)
## Warning: package 'forecast' was built under R version 4.5.3
serie.pib <-
  read_excel("C:/Users/MINEDUCYT/Downloads/PIB a precios corrientes  trimestral.xls",
             col_types = c("skip", "numeric"),
             skip = 7)

serie.pib.ts <- ts(data = serie.pib,
                   start = c(2009, 1),
                   frequency = 4)

serie.pib.ts %>% 
  autoplot(main = "PIB Trimestral a Precios Corrientes, El Salvador 2009-2025",
           xlab = "Años/Trimestres",
           ylab = "Millones de USD")

ma2_4 <- ma(serie.pib.ts, 4, centre = TRUE)

autoplot(serie.pib.ts, main = "PIB Trimestral a Precios Corrientes, El Salvador 2009-2025",
         xlab = "Años/Trimestres",
         ylab = "Millones de USD") +
  autolayer(ma2_4, series = "Tt")
## Warning: Removed 4 rows containing missing values or values outside the scale range
## (`geom_line()`).

library(magrittr)

Yt <- serie.pib.ts                # Serie original
Tt <- ma2_4                       # Media móvil centrada (2x4-MA) como componente de Tendencia Ciclo
SI <- Yt - Tt                     # Diferencia que contiene componentes Estacional e Irregular

St <- tapply(SI, cycle(SI), mean, na.rm = TRUE)   # Promediando los resultados de cada trimestre
# Los factores estacionales deben sumar "0" en el modelo aditivo
St <- St - sum(St) / 4
# Generar la serie de factores para cada valor de la serie original
St <-
  rep(St, len = length(Yt)) %>% ts(start = c(2009, 1), frequency = 4)

autoplot(St,
         main = "Factores Estacionales",
         xlab = "Años/Trimestres",
         ylab = "Factor Estacional")

## 1.2 Generar pronósticos para 2026 completo (diciembre) usando un modelo SARIMA:

1.2.1 Usando la metodología paso a paso mostrada en Clase.

library(TSstudio)
## Warning: package 'TSstudio' was built under R version 4.5.3
library(forecast)

ts_plot(Yt,Xtitle = "Años/Meses")

1.2.2 Orden de integración

library(kableExtra)
## Warning: package 'kableExtra' was built under R version 4.5.3
library(magrittr)

d <- ndiffs(Yt)
D <- nsdiffs(Yt)

ordenes_integracion <- c(d, D)
names(ordenes_integracion) <- c("d", "D")

ordenes_integracion %>% kable(caption = "Ordenes de Integración") %>% kable_material()
Ordenes de Integración
x
d 1
D 1

1.2.3 Verificar los valores para (p,q) & (P,Q)

Yt %>% 
  diff(lag = 4, differences = D) %>% 
  diff(differences = d) %>% 
  ts_cor(lag.max = 16)

1.2.4 Estimación del modelo

library(forecast)
library(ggthemes)
## Warning: package 'ggthemes' was built under R version 4.5.3
modelo_estimado <- Yt %>% 
  Arima(order = c(0, 1, 0),
        seasonal = c(2, 1, 1))

summary(modelo_estimado)
## Series: . 
## ARIMA(0,1,0)(2,1,1)[4] 
## 
## Coefficients:
##         sar1    sar2     sma1
##       0.0964  0.0306  -0.8881
## s.e.  0.1661  0.1499   0.1697
## 
## sigma^2 = 66258:  log likelihood = -433.21
## AIC=874.42   AICc=875.12   BIC=882.92
## 
## Training set error measures:
##                    ME     RMSE      MAE        MPE     MAPE      MASE
## Training set 13.40819 241.5511 128.6044 0.08026422 1.983535 0.3522423
##                    ACF1
## Training set -0.1710487
modelo_estimado %>% autoplot(type="both")+theme_solarized()

modelo_estimado %>% check_res(lag.max = 16)
## Warning: Ignoring 16 observations
## Warning: Ignoring 13 observations
## Warning: Ignoring 5 observations

1.3 Pronóstico Modelo de Holt Winters

1.3.1 ibreria Forecast

library(forecast)

# Estimar el modelo
ModeloHW <- HoltWinters(x = Yt,
                        seasonal = "multiplicative",
                        optim.start = c(0.9, 0.9, 0.9))
ModeloHW
## Holt-Winters exponential smoothing with trend and multiplicative seasonal component.
## 
## Call:
## HoltWinters(x = Yt, seasonal = "multiplicative", optim.start = c(0.9,     0.9, 0.9))
## 
## Smoothing parameters:
##  alpha: 0.7936087
##  beta : 0
##  gamma: 0.09650871
## 
## Coefficients:
##            [,1]
## a  9413.6758348
## b    67.1976250
## s1    0.9755610
## s2    1.0073567
## s3    0.9767203
## s4    1.0418755
# Generar el pronóstico:
PronosticosHW <- forecast(object = ModeloHW, h = 4, level = c(0.95))
PronosticosHW
##         Point Forecast    Lo 95     Hi 95
## 2025 Q4       9249.170 8866.463  9631.877
## 2026 Q1       9618.313 9075.102 10161.525
## 2026 Q2       9391.428 8745.512 10037.345
## 2026 Q3      10087.924 9404.769 10771.080
#Gráfico de la serie original y del pronóstico.
PronosticosHW %>% autoplot()

2) Modelo Indice al precio al consumidor

library(readxl)
Índice_de_precios_al_consumidor <- read_excel("C:/Users/MINEDUCYT/Downloads/Índice de precios al consumidor.xls")
## New names:
## • `` -> `...2`
View(Índice_de_precios_al_consumidor)

2.1 Calcular Yt

library(readxl)
library(forecast)

serie.ipc <- read_excel(
  "C:/Users/MINEDUCYT/Downloads/Índice de precios al consumidor.xls",
  col_types = c("skip", "numeric"),
  skip = 7
)

serie.ipc.ts <- ts(
  data      = serie.ipc,
  start     = c(2009, 1),
  frequency = 12
)

serie.ipc.ts %>%
  autoplot(
    main = "Índice de Precios al Consumidor (IPC), El Salvador 2009-2026",
    xlab = "Años/Meses",
    ylab = "Nivel del índice"
  )

ma12 <- ma(serie.ipc.ts, 12, centre = TRUE)

autoplot(serie.ipc.ts,
         main = "Índice de Precios al Consumidor, El Salvador 2009-2026",
         xlab  = "Años/Meses",
         ylab  = "Nivel del índice") +
  autolayer(ma12, series = "Tendencia (MM 12)")
## Warning: Removed 12 rows containing missing values or values outside the scale range
## (`geom_line()`).

library(magrittr)

Yt2 <- serie.ipc.ts                        # Serie original
Tt2 <- ma12                                # Media móvil centrada (2x12-MA) como componente de Tendencia-Ciclo
SI2 <- Yt2 - Tt2                           # Componentes Estacional e Irregular
St2 <- tapply(SI2, cycle(SI2), mean, na.rm = TRUE)   # Promedio de cada mes

# Los factores estacionales deben sumar "0" en el modelo aditivo
St2 <- St2 - sum(St2) / 12

# Generar la serie de factores para cada valor de la serie original
St2 <- rep(St2, len = length(Yt2)) %>%
  ts(start = c(2009, 1), frequency = 12)

autoplot(St2,
         main = "Factores Estacionales - IPC, El Salvador 2009-2026",
         xlab  = "Años/Meses",
         ylab  = "Factor Estacional")

2.2 Generar pronósticos para 2026 completo (diciembre) usando un modelo SARIMA:

2.2.1 Usando la metodología paso a paso mostrada en Clase.

library(TSstudio)
library(forecast)

ts_plot(Yt2, Xtitle = "Años/Meses")

2.2.2 Orden de integración

library(kableExtra)
library(magrittr)

d2 <- ndiffs(Yt2)
D2 <- nsdiffs(Yt2)
ordenes_integracion2 <- c(d2, D2)
names(ordenes_integracion2) <- c("d", "D")
ordenes_integracion2 %>% kable(caption = "Ordenes de Integración") %>% kable_material()
Ordenes de Integración
x
d 1
D 0

2.2.3 Verificar los valores para (p,q) & (P,Q)

Yt2_diff <- Yt2

if (D2 > 0) Yt2_diff <- diff(Yt2_diff, lag = 12, differences = D2)
if (d2 > 0) Yt2_diff <- diff(Yt2_diff, differences = d2)

ts_cor(Yt2_diff, lag.max = 48)

2.2.4 Estimación del modelo

library(forecast)
library(ggthemes)

modelo_estimado2 <- Arima(Yt2,
                          order    = c(1, 1, 1),
                          seasonal = c(1, 0, 1))
summary(modelo_estimado2)
## Series: Yt2 
## ARIMA(1,1,1)(1,0,1)[12] 
## 
## Coefficients:
##          ar1      ma1    sar1    sma1
##       0.8983  -0.7196  0.0666  0.0921
## s.e.  0.0969   0.1636  0.4478  0.4400
## 
## sigma^2 = 0.2046:  log likelihood = -127.79
## AIC=265.57   AICc=265.87   BIC=282.24
## 
## Training set error measures:
##                      ME      RMSE      MAE       MPE      MAPE      MASE
## Training set 0.05667803 0.4468466 0.304207 0.0489232 0.2686795 0.1397506
##                    ACF1
## Training set 0.08258213
modelo_estimado2 %>% autoplot(type="both")+theme_solarized()

modelo_estimado2 %>% check_res(lag.max = 36)
## Warning: Ignoring 36 observations
## Warning: Ignoring 34 observations
## Warning: Ignoring 4 observations

2.3 Pronóstico Modelo de Holt Winters

2.3.1 ibreria Forecast

library(forecast)

ModeloHW2 <- HoltWinters(x = Yt2,
                         seasonal = "multiplicative",
                         optim.start = c(0.9, 0.9, 0.9))
ModeloHW2
## Holt-Winters exponential smoothing with trend and multiplicative seasonal component.
## 
## Call:
## HoltWinters(x = Yt2, seasonal = "multiplicative", optim.start = c(0.9,     0.9, 0.9))
## 
## Smoothing parameters:
##  alpha: 0.8365872
##  beta : 0.08267408
##  gamma: 1
## 
## Coefficients:
##            [,1]
## a   133.0559166
## b     0.1917751
## s1    1.0057099
## s2    1.0040259
## s3    0.9990727
## s4    0.9968376
## s5    0.9976030
## s6    0.9978137
## s7    0.9942479
## s8    0.9963541
## s9    0.9991928
## s10   1.0020639
## s11   1.0043778
## s12   1.0051413
# Generar el pronóstico:
PronosticosHW2 <- forecast(object = ModeloHW2, h = 8, level = c(0.95))
PronosticosHW2
##          Point Forecast    Lo 95    Hi 95
## May 2026       134.0085 132.9233 135.0937
## Jun 2026       133.9767 132.5136 135.4397
## Jul 2026       133.5073 131.7077 135.3070
## Aug 2026       133.3998 131.2776 135.5221
## Sep 2026       133.6936 131.2513 136.1358
## Oct 2026       133.9132 131.1548 136.6715
## Nov 2026       133.6253 130.5612 136.6893
## Dec 2026       134.0994 130.7123 137.4866
#Gráfico de la serie original y del pronóstico.
PronosticosHW2 %>% autoplot()

3) Importación de Hidrocarburos [en valor US$] SLV 2017-2026 (mayo)

library(readxl)
Importación_de_hidrocarburos <- read_excel("Importación de hidrocarburos.xls")
## New names:
## • `` -> `...2`
View(Importación_de_hidrocarburos)

3.1 Calcular YT

library(readxl)
library(forecast)

# Objeto 1: serie.hid (3 columnas especificadas en col_types → skip + numeric + numeric)
serie.hid <-
  read_excel("Importación de hidrocarburos.xls",
             col_types = c("skip", "numeric"),
             skip = 7)

# Objeto 2: serie.hid.ts (frequency = 3*4 = 12 meses, inicio mes 9 = 3*3)
serie.hid.ts <- ts(data = serie.hid,
                   start = c(2017, 9),
                   frequency = 12)

# Objeto 3: gráfico con 3 parámetros de texto (main, xlab, ylab)
serie.hid.ts %>%
  autoplot(main = "Importación de Hidrocarburos, El Salvador 2017-2026",
           xlab = "Años/Meses",
           ylab = "Millones de USD")

# Objeto 1: ma con order = 3 (media móvil de orden 3)
ma_hid_3 <- ma(serie.hid.ts, 3, centre = TRUE)

# Objeto 2: ma con order = 12 (media móvil de orden 12 = 3×4)
ma_hid_12 <- ma(serie.hid.ts, 12, centre = TRUE)

# Objeto 3: gráfico con 3 parámetros de texto + 1 capa autolayer (series con nombre de 3 letras)
autoplot(serie.hid.ts, main = "Importación de Hidrocarburos, El Salvador 2017-2026",
         xlab = "Años/Meses",
         ylab = "Millones de USD") +
  autolayer(ma_hid_12, series = "Tt3")
## Warning: Removed 12 rows containing missing values or values outside the scale range
## (`geom_line()`).

library(magrittr)

# Objeto 1: Serie original y componentes base
Yt3 <- serie.hid.ts                # Serie original
Tt3 <- ma_hid_12                   # Media móvil centrada (2x12-MA) como componente de Tendencia Ciclo
SI3 <- Yt3 - Tt3                     # Diferencia que contiene componentes Estacional e Irregular

# Objeto 2: Factores estacionales promediados por mes (12 meses = 3×4)
St3 <- tapply(SI3, cycle(SI3), mean, na.rm = TRUE)
# Los factores estacionales deben sumar "0" en el modelo aditivo
St3 <- St3 - sum(St3) / 12           # Se divide entre 12 (meses) en lugar de 4 (trimestres)

# Objeto 3: Serie de factores estacionales replicada para toda la serie
St3 <-
  rep(St, len = length(Yt3)) %>% ts(start = c(2017, 9), frequency = 12)

autoplot(St,
         main = "Factores Estacionales - Importación de Hidrocarburos",
         xlab = "Años/Meses",
         ylab = "Factor Estacional")

## 3.2 Generar pronósticos para 2026 completo (diciembre) usando un modelo SARIMA:

3.2.1 Usando la metodología paso a paso mostrada en Clase.

library(TSstudio)
library(forecast)

# Graficar la serie original de hidrocarburos usando el objeto con terminación 3
ts_plot(Yt3, Xtitle = "Años/Meses", Ytitle = "Millones de USD", title = "Importación de Hidrocarburos - El Salvador")

3.2.2 Orden de integración

library(kableExtra)
library(magrittr)

# Objeto 1: Órdenes de integración regulares y estacionales
d3 <- ndiffs(Yt3)
D3 <- nsdiffs(Yt3)

# Objeto 2: Vector nombrado con 3 etiquetas informativas
ordenes_integracion <- c(d3, D3, d + D)
names(ordenes_integracion) <- c("d (Regular)", "D (Estacional)", "d+D (Total)")

# Objeto 3: Tabla formateada con 3 parámetros de estilo
ordenes_integracion %>%
  kable(caption = "Órdenes de Integración - Importación de Hidrocarburos El Salvador",
        col.names = c("Valor"),
        align = "c") %>%
  kable_material()
Órdenes de Integración - Importación de Hidrocarburos El Salvador
Valor
d (Regular) 1
D (Estacional) 0
d+D (Total) 2

3.2.3 Verificar los valores para (p,q) & (P,Q)

Yt_diff3 <- Yt3
if (D3 > 0) Yt_diff3 <- diff(Yt_diff3, lag = 12, differences = D3)
if (d3 > 0) Yt_diff3 <- diff(Yt_diff3, differences = d3)
ts_cor(na.omit(Yt_diff3), lag.max = 36)

3.2.4 Estimación del modelo

library(forecast)
library(ggthemes)

modelo_estimado3 <- Yt3 %>%
  Arima(order = c(2, 1, 1),
        seasonal = c(0, 0, 0))

summary(modelo_estimado3)
## Series: . 
## ARIMA(2,1,1) 
## 
## Coefficients:
##           ar1      ar2      ma1
##       -0.3745  -0.2868  -0.2449
## s.e.   0.2092   0.1355   0.2085
## 
## sigma^2 = 955.7:  log likelihood = -493.46
## AIC=994.92   AICc=995.33   BIC=1005.42
## 
## Training set error measures:
##                    ME     RMSE      MAE       MPE     MAPE      MASE
## Training set 2.544688 30.30859 24.31344 -2.121764 16.91289 0.5272594
##                     ACF1
## Training set -0.01399102
modelo_estimado3 %>%
  autoplot(type = "both") +
  theme_solarized()

modelo_estimado3 %>% check_res(lag.max = 36)
## Warning: Ignoring 36 observations
## Warning: Ignoring 34 observations
## Warning: Ignoring 4 observations

3.3 Pronóstico Modelo de Holt Winters

3.3.1 ibreria Forecast

library(forecast)

ModeloHW3 <- HoltWinters(x = Yt,
                         seasonal = "additive",
                         optim.start = c(0.3, 0.3, 0.3))
ModeloHW3
## Holt-Winters exponential smoothing with trend and additive seasonal component.
## 
## Call:
## HoltWinters(x = Yt, seasonal = "additive", optim.start = c(0.3,     0.3, 0.3))
## 
## Smoothing parameters:
##  alpha: 0.6801416
##  beta : 0
##  gamma: 0.28074
## 
## Coefficients:
##          [,1]
## a  9418.22408
## b    67.19762
## s1 -203.81263
## s2   39.80667
## s3  -70.16009
## s4  341.02942
PronosticosHW3 <- forecast(object = ModeloHW3, h = 9, level = c(0.93))
PronosticosHW3
##         Point Forecast    Lo 93     Hi 93
## 2025 Q4       9281.609 8827.563  9735.655
## 2026 Q1       9592.426 9043.314 10141.538
## 2026 Q2       9549.657 8919.664 10179.650
## 2026 Q3      10028.044 9326.433 10729.655
## 2026 Q4       9550.400 8766.519 10334.281
## 2027 Q1       9861.216 9018.699 10703.734
## 2027 Q2       9818.447 8921.116 10715.778
## 2027 Q3      10296.834 9347.851 11245.818
## 2027 Q4       9819.190 8807.864 10830.517
PronosticosHW3 %>%
  autoplot(main = "Pronóstico Importación de Hidrocarburos, El Salvador 2026",
           xlab = "Años/Meses",
           ylab = "Millones de USD")

Validación Cruzada

library(forecast)
library(dplyr)
library(tsibble)
library(fable)
library(fabletools)

# ── PIB (Yt) ─────────────────────────────────────────────────────────────────
Yt_tb <- Yt %>% as_tsibble() %>% rename(PIB = value)

data.cv.pib3 <- Yt_tb %>%
  stretch_tsibble(.init = 36, .step = 1)

TSCV_PIB3 <- data.cv.pib3 %>%
  model(
    ARIMA3   = ARIMA(PIB ~ pdq(0,1,0) + PDQ(2,1,1)),
    HoltWin3 = ETS(PIB ~ error("M") + trend("A") + season("M"))
  ) %>%
  forecast(h = 3) %>%
  accuracy(Yt_tb)

print(TSCV_PIB3)
## # A tibble: 2 × 10
##   .model   .type    ME  RMSE   MAE   MPE  MAPE  MASE RMSSE  ACF1
##   <chr>    <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 ARIMA3   Test   125.  601.  351.  1.33  5.07 0.961  1.26 0.610
## 2 HoltWin3 Test   160.  741.  346.  1.96  5.11 0.947  1.55 0.656
# ── IPC / Precios (Yt2) ───────────────────────────────────────────────────────
Yt2_tb <- Yt2 %>% as_tsibble() %>% rename(IPC = value)

data.cv.ipc3 <- Yt2_tb %>%
  stretch_tsibble(.init = 36, .step = 1)

TSCV_IPC3 <- data.cv.ipc3 %>%
  model(
    ARIMA3   = ARIMA(IPC ~ pdq(1,1,1) + PDQ(1,0,0)),
    HoltWin3 = ETS(IPC ~ error("M") + trend("A") + season("M"))
  ) %>%
  forecast(h = 3) %>%
  accuracy(Yt2_tb)

print(TSCV_IPC3)
## # A tibble: 2 × 10
##   .model   .type      ME  RMSE   MAE     MPE  MAPE  MASE RMSSE  ACF1
##   <chr>    <chr>   <dbl> <dbl> <dbl>   <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 ARIMA3   Test   0.0451 0.706 0.511  0.0345 0.439 0.235 0.218 0.711
## 2 HoltWin3 Test  -0.242  0.976 0.708 -0.214  0.613 0.325 0.301 0.817
# ── Hidrocarburos (Yt3) ───────────────────────────────────────────────────────
Yt3_tb <- Yt3 %>% as_tsibble() %>% rename(Hidrocarburos = value)

data.cv.hid3 <- Yt3_tb %>%
  stretch_tsibble(.init = 36, .step = 1)

TSCV_HID3 <- data.cv.hid3 %>%
  model(
    ARIMA3   = ARIMA(Hidrocarburos ~ pdq(2,1,1) + PDQ(0,0,0)),
    HoltWin3 = ETS(Hidrocarburos ~ error("A") + trend("A") + season("N"))
  ) %>%
  forecast(h = 3) %>%
  accuracy(Yt3_tb)

print(TSCV_HID3)
## # A tibble: 2 × 10
##   .model   .type    ME  RMSE   MAE    MPE  MAPE  MASE RMSSE  ACF1
##   <chr>    <chr> <dbl> <dbl> <dbl>  <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 ARIMA3   Test   3.90  35.9  28.1 0.629   14.6 0.609 0.615 0.247
## 2 HoltWin3 Test   1.39  36.6  28.7 0.0435  15.5 0.623 0.627 0.337

Para las variables macroeconómicas de baja volatilidad, los resultados de la validación cruzada (\(h = 3\)) muestran un desempeño sobresaliente en términos de error porcentual absoluto medio (MAPE). En el caso del IPC, ambos modelos logran una precisión excepcional con errores promedio inferiores al 1%, destacando ARIMA3 con un MAPE de apenas 0.439% frente al 0.613% de HoltWin3. Por su parte, el PIB también presenta un pronóstico altamente preciso, donde ARIMA3 se desvía en promedio un 5.07% de los valores reales y HoltWin3 un 5.11%, lo que confirma que las inercias y tendencias de estas series están excelentemente capturadas, otorgándole una ligera ventaja al modelo ARIMA en ambos escenarios.

Por el contrario, el sector de Hidrocarburos refleja una mayor complejidad y volatilidad, lo que se traduce en los márgenes de error más elevados del análisis. El modelo ARIMA3 registra un MAPE de 14.6%, superando sutilmente a HoltWin3, el cual alcanza un 15.5%. Aunque estos valores entran en el rango de un pronóstico aceptable o “bueno” para series sectoriales típicamente inestables, el comportamiento general en las tres variables consolida a ARIMA3 como la herramienta más robusta y consistente para realizar las proyecciones fuera de la muestra.