Importacón de Datos.

library(readxl)
PIB_trim <- read_excel("PIB a precios corrientes  trimestral.xls", 
    sheet = "Datos", 
    col_types = c("skip", "numeric"), 
    skip = 7)
names(PIB_trim)<-c("PIB_trim")

Convertir en objeto de Serie Temporal (ts)

PIB_trim.ts<-ts(data = PIB_trim$PIB_trim,start = c(2009,1),frequency = 4) |> print()
##         Qtr1    Qtr2    Qtr3    Qtr4
## 2009 4436.39 4312.85 4625.05 4375.00
## 2010 4579.71 4498.45 4994.77 4727.87
## 2011 5163.09 5032.40 5360.43 5176.52
## 2012 5401.29 5225.97 5582.38 5208.33
## 2013 5550.62 5428.02 5803.99 5434.08
## 2014 5701.62 5589.75 5868.02 5617.57
## 2015 5870.22 5828.24 6122.20 5695.10
## 2016 6181.80 5962.28 6352.24 5934.25
## 2017 6271.06 6150.90 6622.97 6158.89
## 2018 6529.02 6480.43 6852.52 6402.12
## 2019 6714.13 6691.76 7073.12 6463.49
## 2020 5377.69 6119.98 6960.03 6748.64
## 2021 7208.52 7239.80 7846.18 7556.38
## 2022 7957.48 7930.34 8425.91 7913.51
## 2023 8422.35 8372.77 8856.80 8301.40
## 2024 8728.83 8539.41 9310.10 8657.02
## 2025 9134.58 9089.93 9826.57

Cálculo automático del modelo ARIMA

library(forecast)
## Warning: package 'forecast' was built under R version 4.5.3
library(TSstudio)
## Warning: package 'TSstudio' was built under R version 4.5.3
PIB_trim.arima.automatico<-auto.arima(y = PIB_trim.ts)
summary(PIB_trim.arima.automatico)
## Series: PIB_trim.ts 
## ARIMA(1,0,0)(0,1,1)[4] with drift 
## 
## Coefficients:
##          ar1     sma1    drift
##       0.8163  -0.7773  72.7765
## s.e.  0.0871   0.1493  11.1742
## 
## sigma^2 = 61796:  log likelihood = -437.33
## AIC=882.66   AICc=883.35   BIC=891.23
## 
## Training set error measures:
##                     ME     RMSE      MAE        MPE     MAPE      MASE
## Training set -2.254541 235.2437 125.0171 -0.2393929 1.926357 0.3424168
##                     ACF1
## Training set -0.07401954

Pronóstico usando el modelo automático.

library(forecast)

#Tabla

pronostico.arima.automatico<-forecast(object = PIB_trim.arima.automatico,h = 4,level = c(.95)) |> print()
##         Point Forecast    Lo 95     Hi 95
## 2025 Q4       9230.649 8743.402  9717.896
## 2026 Q1       9471.137 8842.191 10100.084
## 2026 Q2       9372.825 8665.046 10080.604
## 2026 Q3       9911.294 9155.545 10667.043
#Gráfica

PIB_trim.arima.automatico |> forecast(h = 4,level = c(.95)) |> autoplot()

Cálculo “manual” del modelo

library(kableExtra)
## Warning: package 'kableExtra' was built under R version 4.5.3
d<-ndiffs(PIB_trim.ts)
D<-nsdiffs(PIB_trim.ts)
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
library(TSstudio)
PIB_trim.ts_diff<-PIB_trim.ts |>  
  diff(lag = 4,diffences=D) |> 
  diff(diffences=d)
PIB_trim.ts_diff |> 
  ts_cor(lag.max = 3*4)

INTERPRETACIÓN: Parte regular p = 0, q = 0. Parte estacional P = 2, Q = 0

library(forecast)
PIB_trim.arima.manual<-Arima(y = PIB_trim.ts,order = c(0,1,0), seasonal = c(2,1,0)) |> print()
## Series: PIB_trim.ts 
## ARIMA(0,1,0)(2,1,0)[4] 
## 
## Coefficients:
##          sar1     sar2
##       -0.5738  -0.2585
## s.e.   0.1191   0.1161
## 
## sigma^2 = 78175:  log likelihood = -436.97
## AIC=879.94   AICc=880.35   BIC=886.32

2.1. Pronóstico usando el modelo manual

library(forecast)

#Tabla

pronostico.arima.manual<-forecast(object = PIB_trim.arima.manual,h = 4,level = c(0.95)) |> print()
##         Point Forecast    Lo 95     Hi 95
## 2025 Q4       9240.649 8692.648  9788.651
## 2026 Q1       9710.488 8935.497 10485.479
## 2026 Q2       9618.917 8669.751 10568.084
## 2026 Q3      10301.003 9205.000 11397.006
#Gráfica

PIB_trim.arima.manual |> forecast(h = 4,level = c(.95)) |> autoplot()

2. Modelo Holt-Winters

PIB_trim.hw <- HoltWinters(PIB_trim.ts, seasonal = "additive")
PIB_trim.hw
## Holt-Winters exponential smoothing with trend and additive seasonal component.
## 
## Call:
## HoltWinters(x = PIB_trim.ts, seasonal = "additive")
## 
## Smoothing parameters:
##  alpha: 0.6801432
##  beta : 0
##  gamma: 0.2807351
## 
## Coefficients:
##          [,1]
## a  9418.22626
## b    67.19762
## s1 -203.81198
## s2   39.80686
## s3  -70.16048
## s4  341.02661
#Tabla
pronostico.hw <- forecast(object = PIB_trim.hw, h = 4, level = c(80, 95))
pronostico.hw
##         Point Forecast    Lo 80     Hi 80    Lo 95     Hi 95
## 2025 Q4       9281.612 8960.469  9602.755 8790.466  9772.758
## 2026 Q1       9592.428 9204.045  9980.812 8998.447 10186.410
## 2026 Q2       9549.659 9104.069  9995.249 8868.187 10231.130
## 2026 Q3      10028.043 9531.798 10524.289 9269.102 10786.985
#Gráfica
PIB_trim.hw |> forecast(h = 4, level = c(80, 95)) |> plot()

4. Validación cruzada (tsCV) y MAPE

f_arima_manual <- function(x, h) {
  tryCatch(forecast(Arima(x, order = c(0, d, 0), seasonal = c(2, D, 0)), h = h),
           error = function(e) list(mean = ts(rep(NA, h))))
}
f_arima_auto <- function(x, h) {
  tryCatch(forecast(auto.arima(x), h = h),
           error = function(e) list(mean = ts(rep(NA, h))))
}
f_hw <- function(x, h) {
  tryCatch(forecast(HoltWinters(x, seasonal = "additive"), h = h),
           error = function(e) list(mean = ts(rep(NA, h))))
}

e_manual_pib <- tsCV(PIB_trim.ts, f_arima_manual, h = 1)
e_auto_pib   <- tsCV(PIB_trim.ts, f_arima_auto,   h = 1)
e_hw_pib     <- tsCV(PIB_trim.ts, f_hw,           h = 1)

mape_manual_pib <- mean(abs(e_manual_pib / PIB_trim.ts), na.rm = TRUE) * 100
mape_auto_pib   <- mean(abs(e_auto_pib   / PIB_trim.ts), na.rm = TRUE) * 100
mape_hw_pib     <- mean(abs(e_hw_pib     / PIB_trim.ts), na.rm = TRUE) * 100

data.frame(Modelo = c("SARIMA manual", "SARIMA auto.arima", "Holt-Winters"),
           MAPE_CV = c(mape_manual_pib, mape_auto_pib, mape_hw_pib)) %>%
  kable(caption = "MAPE de validación cruzada - PIB", digits = 2)
MAPE de validación cruzada - PIB
Modelo MAPE_CV
SARIMA manual 3.01
SARIMA auto.arima 3.50
Holt-Winters 2.58

Índice de Precios al Consumidor (IPC general) 2009 - 2026

Importación de datos

IPC_general <- read_excel("Índice de precios al consumidor.xls",
                           sheet = "Datos", col_types = c("skip", "numeric"),
                           skip = 7)
names(IPC_general) <- c("IPC_general")
head(IPC_general)
## # A tibble: 6 × 1
##   IPC_general
##         <dbl>
## 1        99.5
## 2       100  
## 3       100. 
## 4       100. 
## 5       100. 
## 6       100.0
tail(IPC_general)
## # A tibble: 6 × 1
##   IPC_general
##         <dbl>
## 1        131.
## 2        131 
## 3        132.
## 4        132.
## 5        133.
## 6        134.

Convertir en objeto de Serie Temporal (ts)

IPC_general.ts <- ts(data = IPC_general$IPC_general, start = c(2009, 1),
                      frequency = 12)
IPC_general.ts
##         Jan    Feb    Mar    Apr    May    Jun    Jul    Aug    Sep    Oct
## 2009  99.53 100.00 100.08 100.36 100.40  99.99  99.79  99.73  99.03 100.41
## 2010 100.57 100.89 100.71 100.50 100.96 100.98 100.81 101.11 101.78 102.24
## 2011 102.96 103.63 106.71 107.23 107.29 107.57 107.69 107.40 107.32 107.48
## 2012 108.00 108.16 108.83 108.53 107.94 107.61 107.80 108.24 108.33 108.18
## 2013 109.05 109.54 108.85 108.69 108.91 108.78 108.87 109.06 108.91 109.00
## 2014 109.72 109.99 109.47 109.72 110.15 110.77 111.04 110.91 110.97 110.40
## 2015 108.56 109.10 109.11 109.33 109.24 109.16 108.82 108.41 110.76 110.69
## 2016 110.37 110.32 110.05 110.13 110.24 110.12 109.85 109.51 109.79 109.78
## 2017 110.69 110.92 111.00 111.19 111.26 111.24 111.10 111.22 111.36 111.62
## 2018 112.05 111.93 111.97 112.11 112.26 112.42 112.71 112.76 113.02 112.82
## 2019 112.44 112.69 112.87 113.01 112.85 112.56 112.16 111.99 112.04 112.17
## 2020 112.00 112.09 111.69 111.94 112.59 112.49 111.82 111.56 111.81 111.98
## 2021 113.19 114.08 114.81 114.84 115.51 116.36 116.63 117.10 117.95 118.92
## 2022 120.73 121.71 122.32 123.43 124.47 124.99 125.56 125.87 126.76 127.63
## 2023 128.97 129.08 128.97 128.88 129.18 129.17 129.44 129.67 130.14 130.32
## 2024 130.00 130.08 130.45 130.71 131.09 131.47 130.96 130.42 130.04 129.93
## 2025 130.08 130.26 130.30 130.44 130.86 131.29 130.81 130.89 131.26 131.41
## 2026 131.60 132.18 133.12 133.74                                          
##         Nov    Dec
## 2009 100.00 100.44
## 2010 102.13 102.77
## 2011 107.29 107.65
## 2012 108.13 108.59
## 2013 108.98 109.51
## 2014 109.50 108.69
## 2015 110.61 110.67
## 2016 109.58 110.39
## 2017 111.81 111.96
## 2018 112.30 112.24
## 2019 112.29 112.15
## 2020 112.20 112.49
## 2021 119.06 119.79
## 2022 127.77 128.21
## 2023 129.34 129.76
## 2024 129.71 130.16
## 2025 130.89 131.00
## 2026
ts_plot(IPC_general.ts, title = "IPC general - El Salvador",
        Ytitle = "Índice", Xtitle = "Año")

Cálculo automático del modelo ARIMA

IPC_general.arima.automatico <- auto.arima(y = IPC_general.ts)
summary(IPC_general.arima.automatico)
## Series: IPC_general.ts 
## ARIMA(0,1,1)(1,0,0)[12] with drift 
## 
## Coefficients:
##          ma1    sar1   drift
##       0.2687  0.1952  0.1666
## s.e.  0.0651  0.0720  0.0479
## 
## sigma^2 = 0.1999:  log likelihood = -125.83
## AIC=259.66   AICc=259.86   BIC=272.99
## 
## Training set error measures:
##                        ME      RMSE       MAE          MPE      MAPE      MASE
## Training set 0.0008628446 0.4427883 0.2994828 -0.001416851 0.2649114 0.1375803
##                    ACF1
## Training set 0.01776955

Pronóstico usando el modelo automático

# El último dato disponible es mayo-2026; faltan 7 meses para llegar a dic-2026
h_ipc <- (2026 - end(IPC_general.ts)[1]) * 12 + (12 - end(IPC_general.ts)[2])
h_ipc
## [1] 8
#Tabla
pronostico.ipc.automatico <- forecast(object = IPC_general.arima.automatico,
                                       h = h_ipc, level = c(80, 95))
pronostico.ipc.automatico
##          Point Forecast    Lo 80    Hi 80    Lo 95    Hi 95
## May 2026       134.0272 133.4542 134.6002 133.1508 134.9035
## Jun 2026       134.2451 133.3195 135.1708 132.8295 135.6608
## Jul 2026       134.2855 133.1086 135.4625 132.4855 136.0855
## Aug 2026       134.4352 133.0518 135.8185 132.3195 136.5508
## Sep 2026       134.6414 133.0787 136.2042 132.2515 137.0314
## Oct 2026       134.8048 133.0812 136.5283 132.1689 137.4407
## Nov 2026       134.8373 132.9668 136.7079 131.9765 137.6981
## Dec 2026       134.9929 132.9860 136.9997 131.9236 138.0621
#Gráfica
IPC_general.arima.automatico |> forecast(h = h_ipc, level = c(80, 95)) |> plot()

Cálculo “manual” del modelo

Calcular las Diferencias

d_ipc <- ndiffs(IPC_general.ts)
D_ipc <- nsdiffs(IPC_general.ts)
ordenes_integracion_ipc <- c(d_ipc, D_ipc)
names(ordenes_integracion_ipc) <- c("d", "D")
ordenes_integracion_ipc %>% kable(caption = "Ordenes de Integración - IPC")
Ordenes de Integración - IPC
x
d 1
D 0

Correlograma de la serie diferenciada

IPC_general.ts_diff <- IPC_general.ts |>
  diff(differences = d_ipc)
IPC_general.ts_diff <-IPC_general.ts
IPC_general.arima.manual <- Arima(y = IPC_general.ts, order = c(1, d_ipc, 1),
                                   seasonal = c(1, D_ipc, 0))
summary(IPC_general.arima.manual)
## Series: IPC_general.ts 
## ARIMA(1,1,1)(1,0,0)[12] 
## 
## Coefficients:
##          ar1      ma1    sar1
##       0.8953  -0.7151  0.1576
## s.e.  0.0979   0.1640  0.0806
## 
## sigma^2 = 0.2036:  log likelihood = -127.81
## AIC=263.61   AICc=263.81   BIC=276.94
## 
## Training set error measures:
##                      ME      RMSE       MAE        MPE      MAPE      MASE
## Training set 0.05653484 0.4468981 0.3036493 0.04881694 0.2682049 0.1394944
##                    ACF1
## Training set 0.08019736

Pronóstico usando el modelo manual

#Tabla
pronostico.ipc.manual <- forecast(object = IPC_general.arima.manual,
                                   h = h_ipc, level = c(80, 95))
pronostico.ipc.manual
##          Point Forecast    Lo 80    Hi 80    Lo 95    Hi 95
## May 2026       134.1254 133.5470 134.7037 133.2409 135.0098
## Jun 2026       134.4789 133.5843 135.3735 133.1107 135.8471
## Jul 2026       134.6591 133.4749 135.8434 132.8480 136.4702
## Aug 2026       134.9008 133.4376 136.3641 132.6629 137.1387
## Sep 2026       135.1642 133.4281 136.9004 132.5091 137.8194
## Oct 2026       135.3715 133.3673 137.3757 132.3064 138.4367
## Nov 2026       135.4540 133.1861 137.7219 131.9856 138.9224
## Dec 2026       135.6186 133.0914 138.1457 131.7536 139.4835
#Gráfica
IPC_general.arima.manual |> forecast(h = h_ipc, level = c(80, 95)) |> plot()

3. Modelo Holt-Winters

IPC_general.hw <- HoltWinters(IPC_general.ts, seasonal = "additive")
IPC_general.hw
## Holt-Winters exponential smoothing with trend and additive seasonal component.
## 
## Call:
## HoltWinters(x = IPC_general.ts, seasonal = "additive")
## 
## Smoothing parameters:
##  alpha: 0.8455747
##  beta : 0.0967454
##  gamma: 1
## 
## Coefficients:
##             [,1]
## a   133.17294284
## b     0.21188622
## s1    0.60293904
## s2    0.39580482
## s3   -0.18112540
## s4   -0.40463606
## s5   -0.27439665
## s6   -0.23426446
## s7   -0.66157399
## s8   -0.37192478
## s9   -0.02939084
## s10   0.28339029
## s11   0.51847483
## s12   0.56705716
#Tabla
pronostico.ipc.hw <- forecast(object = IPC_general.hw, h = h_ipc, level = c(80, 95))
pronostico.ipc.hw
##          Point Forecast    Lo 80    Hi 80    Lo 95    Hi 95
## May 2026       133.9878 133.2940 134.6816 132.9267 135.0488
## Jun 2026       133.9925 133.0463 134.9387 132.5454 135.4396
## Jul 2026       133.6275 132.4504 134.8046 131.8273 135.4277
## Aug 2026       133.6159 132.2164 135.0153 131.4756 135.7561
## Sep 2026       133.9580 132.3392 135.5768 131.4822 136.4337
## Oct 2026       134.2100 132.3720 136.0480 131.3991 137.0209
## Nov 2026       133.9946 131.9360 136.0532 130.8462 137.1429
## Dec 2026       134.4961 132.2145 136.7778 131.0066 137.9856
#Gráfica
IPC_general.hw |> forecast(h = h_ipc, level = c(80, 95)) |> plot()

3. Validación cruzada (tsCV) y MAPE

f_arima_manual_ipc <- function(x, h) {
  tryCatch(forecast(Arima(x, order = c(1, d_ipc, 1), seasonal = c(1, D_ipc, 0)), h = h),
           error = function(e) list(mean = ts(rep(NA, h))))
}
f_arima_auto_ipc <- function(x, h) {
  tryCatch(forecast(auto.arima(x), h = h),
           error = function(e) list(mean = ts(rep(NA, h))))
}
f_hw_ipc <- function(x, h) {
  tryCatch(forecast(HoltWinters(x, seasonal = "additive"), h = h),
           error = function(e) list(mean = ts(rep(NA, h))))
}

e_manual_ipc <- tsCV(IPC_general.ts, f_arima_manual_ipc, h = 1)
e_auto_ipc   <- tsCV(IPC_general.ts, f_arima_auto_ipc,   h = 1)
e_hw_ipc     <- tsCV(IPC_general.ts, f_hw_ipc,           h = 1)

mape_manual_ipc <- mean(abs(e_manual_ipc / IPC_general.ts), na.rm = TRUE) * 100
mape_auto_ipc   <- mean(abs(e_auto_ipc   / IPC_general.ts), na.rm = TRUE) * 100
mape_hw_ipc     <- mean(abs(e_hw_ipc     / IPC_general.ts), na.rm = TRUE) * 100

data.frame(Modelo = c("SARIMA manual", "SARIMA auto.arima", "Holt-Winters"),
           MAPE_CV = c(mape_manual_ipc, mape_auto_ipc, mape_hw_ipc)) %>%
  kable(caption = "MAPE de validación cruzada - IPC", digits = 2)
MAPE de validación cruzada - IPC
Modelo MAPE_CV
SARIMA manual 0.29
SARIMA auto.arima 0.30
Holt-Winters 0.35

Importación de hidrocarburos (valor US$) 2017 - 2026

Importación de datos

Hidrocarburos <- read_excel("Importación de hidrocarburos.xls",
                             sheet = "Datos", col_types = c("skip", "numeric"),
                             skip = 7)
names(Hidrocarburos) <- c("Hidrocarburos")
head(Hidrocarburos)
## # A tibble: 6 × 1
##   Hidrocarburos
##           <dbl>
## 1          94.0
## 2         150. 
## 3          96.3
## 4         112. 
## 5         129. 
## 6         128.
tail(Hidrocarburos)
## # A tibble: 6 × 1
##   Hidrocarburos
##           <dbl>
## 1          181.
## 2          208.
## 3          179.
## 4          157.
## 5          230 
## 6          251.

Convertir en objeto de Serie Temporal (ts)

# La serie inicia en septiembre de 2017
Hidrocarburos.ts <- ts(data = Hidrocarburos$Hidrocarburos, start = c(2017, 9),
                        frequency = 12)
Hidrocarburos.ts
##         Jan    Feb    Mar    Apr    May    Jun    Jul    Aug    Sep    Oct
## 2017                                                          93.97 149.53
## 2018 128.51 128.47 167.53 139.48 143.59 116.46 140.00 152.20 169.09 136.08
## 2019  97.10 131.95 143.68 162.51 107.81 132.04 127.23 106.52 129.90 127.78
## 2020 100.54 111.09  65.87  29.79  53.36  75.73  57.25  71.73  74.83  91.58
## 2021 108.04 145.58 113.48 138.09 164.20 170.94 146.58 146.68 174.96 172.97
## 2022 180.91 265.99 275.49 188.09 264.20 305.72 200.63 224.95 220.88 247.63
## 2023 202.00 203.09 185.03 207.53 225.29 188.08 229.80 240.41 205.84 186.69
## 2024 189.96 215.51 227.91 227.68 203.01 177.83 211.79 147.99 198.96 162.72
## 2025 158.97 192.69 200.53 189.13 177.54 262.91 175.30 177.24 206.81 180.84
## 2026 157.20 230.00 250.91                                                 
##         Nov    Dec
## 2017  96.28 112.07
## 2018 120.74 112.82
## 2019 114.39 125.77
## 2020  81.36 124.39
## 2021 200.09 150.78
## 2022 147.73 223.36
## 2023 190.69 176.43
## 2024 179.72 209.13
## 2025 207.55 179.03
## 2026
ts_plot(Hidrocarburos.ts, title = "Importación de hidrocarburos (valor US$) - El Salvador",
        Ytitle = "Millones de US$", Xtitle = "Año")

Cálculo automático del modelo ARIMA

Hidrocarburos.arima.automatico <- auto.arima(y = Hidrocarburos.ts)
summary(Hidrocarburos.arima.automatico)
## Series: Hidrocarburos.ts 
## ARIMA(0,1,1) 
## 
## Coefficients:
##           ma1
##       -0.5914
## s.e.   0.0749
## 
## sigma^2 = 968.7:  log likelihood = -495.12
## AIC=994.23   AICc=994.35   BIC=999.48
## 
## Training set error measures:
##                    ME     RMSE      MAE       MPE     MAPE      MASE
## Training set 2.755471 30.81951 24.15507 -2.188938 16.75958 0.5238251
##                     ACF1
## Training set -0.02881156

Pronóstico usando el modelo automático

# El último dato disponible es abril-2026; faltan 8 meses para llegar a dic-2026
h_hidro <- (2026 - end(Hidrocarburos.ts)[1]) * 12 + (12 - end(Hidrocarburos.ts)[2])
h_hidro
## [1] 9
#Tabla
pronostico.hidro.automatico <- forecast(object = Hidrocarburos.arima.automatico,
                                         h = h_hidro, level = c(80, 95))
pronostico.hidro.automatico
##          Point Forecast    Lo 80    Hi 80    Lo 95    Hi 95
## Apr 2026       219.8566 179.9706 259.7425 158.8563 280.8568
## May 2026       219.8566 176.7692 262.9440 153.9601 285.7531
## Jun 2026       219.8566 173.7896 265.9235 149.4033 290.3099
## Jul 2026       219.8566 170.9915 268.7217 145.1238 294.5893
## Aug 2026       219.8566 168.3451 271.3681 141.0765 298.6366
## Sep 2026       219.8566 165.8281 273.8850 137.2272 302.4860
## Oct 2026       219.8566 163.4233 276.2898 133.5494 306.1638
## Nov 2026       219.8566 161.1169 278.5962 130.0220 309.6911
## Dec 2026       219.8566 158.8977 280.8155 126.6280 313.0851
#Gráfica
Hidrocarburos.arima.automatico |> forecast(h = h_hidro, level = c(80, 95)) |> plot()

Cálculo “manual” del modelo

Calcular las Diferencias

d_hidro <- ndiffs(Hidrocarburos.ts)
D_hidro <- nsdiffs(Hidrocarburos.ts)
ordenes_integracion_hidro <- c(d_hidro, D_hidro)
names(ordenes_integracion_hidro) <- c("d", "D")
ordenes_integracion_hidro %>% kable(caption = "Ordenes de Integración - Hidrocarburos")
Ordenes de Integración - Hidrocarburos
x
d 1
D 0

Correlograma de la serie diferenciada

Hidrocarburos.ts_diff <- Hidrocarburos.ts |>
  diff(differences = d_hidro)
Hidrocarburos.ts_diff |>
  ts_cor(lag.max = 3 * 12)

Parte regular p = 1, q = 0. Parte estacional P = 0, Q = 1.

Hidrocarburos.arima.manual <- Arima(y = Hidrocarburos.ts, order = c(1, d_hidro, 0),
                                     seasonal = c(0, D_hidro, 1))
summary(Hidrocarburos.arima.manual)
## Series: Hidrocarburos.ts 
## ARIMA(1,1,0)(0,0,1)[12] 
## 
## Coefficients:
##           ar1     sma1
##       -0.4201  -0.0627
## s.e.   0.0909   0.1060
## 
## sigma^2 = 1096:  log likelihood = -500.82
## AIC=1007.63   AICc=1007.88   BIC=1015.51
## 
## Training set error measures:
##                    ME     RMSE      MAE       MPE     MAPE     MASE       ACF1
## Training set 2.109777 32.62097 25.60527 -1.994129 17.23583 0.555274 -0.1429424

Pronóstico usando el modelo manual

#Tabla
pronostico.hidro.manual <- forecast(object = Hidrocarburos.arima.manual,
                                     h = h_hidro, level = c(80, 95))
pronostico.hidro.manual
##          Point Forecast    Lo 80    Hi 80    Lo 95    Hi 95
## Apr 2026       242.6121 200.1842 285.0401 177.7243 307.5000
## May 2026       247.2142 198.1681 296.2603 172.2047 322.2237
## Jun 2026       240.3821 181.7698 298.9945 150.7422 330.0220
## Jul 2026       246.3980 181.0274 311.7687 146.4223 346.3738
## Aug 2026       246.2435 174.2055 318.2814 136.0709 356.4160
## Sep 2026       244.3167 166.3916 322.2419 125.1405 363.4929
## Oct 2026       246.0412 162.5601 329.5223 118.3679 373.7145
## Nov 2026       244.3220 155.6654 332.9787 108.7334 379.9107
## Dec 2026       245.9874 152.4279 339.5468 102.9006 389.0742
#Gráfica
Hidrocarburos.arima.manual |> forecast(h = h_hidro, level = c(80, 95)) |> plot()

Modelo Holt-Winters

Hidrocarburos.hw <- HoltWinters(Hidrocarburos.ts, seasonal = "additive")
Hidrocarburos.hw
## Holt-Winters exponential smoothing with trend and additive seasonal component.
## 
## Call:
## HoltWinters(x = Hidrocarburos.ts, seasonal = "additive")
## 
## Smoothing parameters:
##  alpha: 0.3835968
##  beta : 0
##  gamma: 0.2571005
## 
## Coefficients:
##           [,1]
## a   211.352220
## b    -0.390676
## s1    2.318810
## s2    7.617968
## s3   12.709424
## s4   -6.089651
## s5   -4.940267
## s6   16.779110
## s7    3.016031
## s8   -1.753818
## s9   -2.223729
## s10 -20.839227
## s11  16.858472
## s12  21.816103
# Tabla

pronostico.hidro.hw <- forecast(object = Hidrocarburos.hw, h = h_hidro, level = c(80, 95))
pronostico.hidro.hw
##          Point Forecast    Lo 80    Hi 80    Lo 95    Hi 95
## Apr 2026       213.2804 169.2938 257.2669 146.0087 280.5520
## May 2026       218.1888 171.0771 265.3006 146.1376 290.2400
## Jun 2026       222.8896 172.8475 272.9318 146.3567 299.4225
## Jul 2026       203.6999 150.8896 256.5101 122.9336 284.4661
## Aug 2026       204.4586 149.0183 259.8988 119.6700 289.2471
## Sep 2026       225.7873 167.8362 283.7383 137.1588 314.4157
## Oct 2026       211.6335 151.2761 271.9910 119.3247 303.9423
## Nov 2026       206.4730 143.8014 269.1446 110.6251 302.3209
## Dec 2026       205.6124 140.7092 270.5156 106.3515 304.8733
#Gráfica
Hidrocarburos.hw |> forecast(h = h_hidro, level = c(80, 95)) |> plot()

Validación cruzada (tsCV) y MAPE

f_arima_manual_hidro <- function(x, h) {
  tryCatch(forecast(Arima(x, order = c(1, d_hidro, 0), seasonal = c(0, D_hidro, 1)), h = h),
           error = function(e) list(mean = ts(rep(NA, h))))
}
f_arima_auto_hidro <- function(x, h) {
  tryCatch(forecast(auto.arima(x), h = h),
           error = function(e) list(mean = ts(rep(NA, h))))
}
f_hw_hidro <- function(x, h) {
  tryCatch(forecast(HoltWinters(x, seasonal = "additive"), h = h),
           error = function(e) list(mean = ts(rep(NA, h))))
}

e_manual_hidro <- tsCV(Hidrocarburos.ts, f_arima_manual_hidro, h = 1)
e_auto_hidro   <- tsCV(Hidrocarburos.ts, f_arima_auto_hidro,   h = 1)
e_hw_hidro     <- tsCV(Hidrocarburos.ts, f_hw_hidro,           h = 1)

mape_manual_hidro <- mean(abs(e_manual_hidro / Hidrocarburos.ts), na.rm = TRUE) * 100
mape_auto_hidro   <- mean(abs(e_auto_hidro   / Hidrocarburos.ts), na.rm = TRUE) * 100
mape_hw_hidro     <- mean(abs(e_hw_hidro     / Hidrocarburos.ts), na.rm = TRUE) * 100

data.frame(Modelo = c("SARIMA manual", "SARIMA auto.arima", "Holt-Winters"),
           MAPE_CV = c(mape_manual_hidro, mape_auto_hidro, mape_hw_hidro)) %>%
  kable(caption = "MAPE de validación cruzada - Hidrocarburos", digits = 2)
MAPE de validación cruzada - Hidrocarburos
Modelo MAPE_CV
SARIMA manual 17.36
SARIMA auto.arima 17.59
Holt-Winters 21.19