1

I'd like to use lagged external regressors in my VAR forecast. Using the VAR() function from the fable package, I am able to fit a model, but I can't use it to forecast, as I return NAs for the dependent variables. My reprex follows examples from Forecasting: Principles and Practice v3.

Thanks in advance for any guidance.

require(fpp3)
#> Loading required package: fpp3
#> ── Attaching packages ──────────────────────────────────────────── fpp3 0.4.0 ──
#> ✔ tibble      3.1.7      ✔ tsibble     1.0.1 
#> ✔ dplyr       1.0.9      ✔ tsibbledata 0.3.0 
#> ✔ tidyr       1.1.3      ✔ feasts      0.2.2 
#> ✔ lubridate   1.7.10     ✔ fable       0.3.1 
#> ✔ ggplot2     3.3.5
#> ── Conflicts ───────────────────────────────────────────────── fpp3_conflicts ──
#> ✖ lubridate::date()    masks base::date()
#> ✖ dplyr::filter()      masks stats::filter()
#> ✖ tsibble::intersect() masks base::intersect()
#> ✖ tsibble::interval()  masks lubridate::interval()
#> ✖ dplyr::lag()         masks stats::lag()
#> ✖ tsibble::setdiff()   masks base::setdiff()
#> ✖ tsibble::union()     masks base::union()

us_change <- fpp3::us_change

fit <- us_change %>%
  model(
    xregs_lag1 = VAR(vars(Consumption, Income) ~ xreg(Unemployment, lag(Unemployment, 1)))
  )

fit
#> # A mable: 1 x 1
#>         xregs_lag1
#>            <model>
#> 1 <VAR(5) w/ mean>

new_data_ex <- new_data(us_change, 4) %>% 
      mutate(Unemployment = mean(us_change$Unemployment)) 

#############
# Here I tried creating a new_data frame that included one lag of Unemployment, and pass that to the new_data argument of forecast, but it doesn't work either
#
# new_data_ex_lags <- us_change %>% 
#    tail(1) %>% 
#    bind_rows(new_data_ex) %>% 
#    select(colnames(new_data_ex))
#############

fit %>%
  select(xregs_lag1) %>%
  forecast(new_data = new_data_ex)
#> # A fable: 4 x 6 [1Q]
#> # Key:     .model [1]
#>   .model     Quarter .distribution .mean_Consumption .mean_Income Unemployment
#>   <chr>        <qtr>        <dist>             <dbl>        <dbl>        <dbl>
#> 1 xregs_lag1 2019 Q3        MVN[2]                NA           NA      0.00101
#> 2 xregs_lag1 2019 Q4        MVN[2]                NA           NA      0.00101
#> 3 xregs_lag1 2020 Q1        MVN[2]                NA           NA      0.00101
#> 4 xregs_lag1 2020 Q2        MVN[2]                NA           NA      0.00101


fit %>%
  select(xregs_lag1) %>% 
  report()
#> Series: Consumption, Income 
#> Model: VAR(5) w/ mean 
#> 
#> Coefficients for Consumption:
#>       lag(Consumption,1)  lag(Income,1)  lag(Consumption,2)  lag(Income,2)
#>                   0.1156         0.1062              0.1479         0.0079
#> s.e.              0.0772         0.0483              0.0753         0.0509
#>       lag(Consumption,3)  lag(Income,3)  lag(Consumption,4)  lag(Income,4)
#>                   0.2248        -0.0207             -0.0729        -0.0544
#> s.e.              0.0730         0.0499              0.0746         0.0500
#>       lag(Consumption,5)  lag(Income,5)  constant  Unemployment
#>                  -0.0217         0.0327    0.3923       -0.8602
#> s.e.              0.0708         0.0491    0.0923        0.1331
#>       lag(Unemployment, 1)
#>                     0.4563
#> s.e.                0.1402
#> 
#> Coefficients for Income:
#>       lag(Consumption,1)  lag(Income,1)  lag(Consumption,2)  lag(Income,2)
#>                   0.3715        -0.2991              0.0836        -0.0410
#> s.e.              0.1212         0.0758              0.1182         0.0799
#>       lag(Consumption,3)  lag(Income,3)  lag(Consumption,4)  lag(Income,4)
#>                   0.4531        -0.1445              0.2481        -0.2475
#> s.e.              0.1145         0.0783              0.1170         0.0785
#>       lag(Consumption,5)  lag(Income,5)  constant  Unemployment
#>                  -0.1270        -0.1878    0.6142       -0.1100
#> s.e.              0.1111         0.0771    0.1449        0.2089
#>       lag(Unemployment, 1)
#>                    -0.0401
#> s.e.                0.2201
#> 
#> Residual covariance matrix:
#>             Consumption Income
#> Consumption      0.2602 0.1341
#> Income           0.1341 0.6410
#> 
#> log likelihood = -350.43
#> AIC = 760.86 AICc = 772.34   BIC = 858.74

Created on 2022-07-22 by the reprex package (v2.0.0)

CaseyR
  • 55
  • 6

1 Answers1

2

Using lag() with VAR() models was not fully implemented, but I have added support for this in the development version of the fable package (https://github.com/tidyverts/fable/commit/bb15c9462b80850565aee13d8f9b33e49dfd0f33).

There are some other changes not yet pushed to CRAN such as how forecast means are represented in the fable, but the code is otherwise the same.

require(fpp3)
#> Loading required package: fpp3
#> ── Attaching packages ──────────────────────────────────────────── fpp3 0.4.0 ──
#> ✔ tibble      3.1.7          ✔ tsibble     1.1.1     
#> ✔ dplyr       1.0.9          ✔ tsibbledata 0.4.0     
#> ✔ tidyr       1.2.0          ✔ feasts      0.2.2     
#> ✔ lubridate   1.8.0          ✔ fable       0.3.1.9000
#> ✔ ggplot2     3.3.6
#> ── Conflicts ───────────────────────────────────────────────── fpp3_conflicts ──
#> ✖ lubridate::date()    masks base::date()
#> ✖ dplyr::filter()      masks stats::filter()
#> ✖ tsibble::intersect() masks base::intersect()
#> ✖ tsibble::interval()  masks lubridate::interval()
#> ✖ dplyr::lag()         masks stats::lag()
#> ✖ tsibble::setdiff()   masks base::setdiff()
#> ✖ tsibble::union()     masks base::union()

us_change <- fpp3::us_change

fit <- us_change %>%
  model(
    xregs_lag1 = VAR(vars(Consumption, Income) ~ xreg(Unemployment, lag(Unemployment, 1)))
  )

fit
#> # A mable: 1 x 1
#>         xregs_lag1
#>            <model>
#> 1 <VAR(5) w/ mean>

new_data_ex <- new_data(us_change, 4) %>% 
  mutate(Unemployment = mean(us_change$Unemployment)) 

#############
# Here I tried creating a new_data frame that included one lag of Unemployment, and pass that to the new_data argument of forecast, but it doesn't work either
#
# new_data_ex_lags <- us_change %>% 
#    tail(1) %>% 
#    bind_rows(new_data_ex) %>% 
#    select(colnames(new_data_ex))
#############

fit %>%
  select(xregs_lag1) %>%
  forecast(new_data = new_data_ex)
#> Warning in if (is_transformed) {: the condition has length > 1 and only the
#> first element will be used
#> # A fable: 4 x 5 [1Q]
#> # Key:     .model [1]
#>   .model     Quarter .distribution .mean[,"Consumption… [,"Income"] Unemployment
#>   <chr>        <qtr>        <dist>                <dbl>       <dbl>        <dbl>
#> 1 xregs_lag1 2019 Q3        MVN[2]                0.548       0.657      0.00101
#> 2 xregs_lag1 2019 Q4        MVN[2]                0.679       0.316      0.00101
#> 3 xregs_lag1 2020 Q1        MVN[2]                0.763       0.832      0.00101
#> 4 xregs_lag1 2020 Q2        MVN[2]                0.697       0.733      0.00101


fit %>%
  select(xregs_lag1) %>% 
  report()
#> Series: Consumption, Income 
#> Model: VAR(5) w/ mean 
#> 
#> Coefficients for Consumption:
#>       lag(Consumption,1)  lag(Income,1)  lag(Consumption,2)  lag(Income,2)
#>                   0.1156         0.1062              0.1479         0.0079
#> s.e.              0.0772         0.0483              0.0753         0.0509
#>       lag(Consumption,3)  lag(Income,3)  lag(Consumption,4)  lag(Income,4)
#>                   0.2248        -0.0207             -0.0729        -0.0544
#> s.e.              0.0730         0.0499              0.0746         0.0500
#>       lag(Consumption,5)  lag(Income,5)  constant  Unemployment
#>                  -0.0217         0.0327    0.3923       -0.8602
#> s.e.              0.0708         0.0491    0.0923        0.1331
#>       lag(Unemployment, 1)
#>                     0.4563
#> s.e.                0.1402
#> 
#> Coefficients for Income:
#>       lag(Consumption,1)  lag(Income,1)  lag(Consumption,2)  lag(Income,2)
#>                   0.3715        -0.2991              0.0836        -0.0410
#> s.e.              0.1212         0.0758              0.1182         0.0799
#>       lag(Consumption,3)  lag(Income,3)  lag(Consumption,4)  lag(Income,4)
#>                   0.4531        -0.1445              0.2481        -0.2475
#> s.e.              0.1145         0.0783              0.1170         0.0785
#>       lag(Consumption,5)  lag(Income,5)  constant  Unemployment
#>                  -0.1270        -0.1878    0.6142       -0.1100
#> s.e.              0.1111         0.0771    0.1449        0.2089
#>       lag(Unemployment, 1)
#>                    -0.0401
#> s.e.                0.2201
#> 
#> Residual covariance matrix:
#>             Consumption Income
#> Consumption      0.2602 0.1341
#> Income           0.1341 0.6410
#> 
#> log likelihood = -350.43
#> AIC = 760.86 AICc = 772.34   BIC = 858.74

Created on 2022-07-23 by the reprex package (v2.0.1)