--- title: "Regressors and events" output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{Regressors and events} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- ```{r, include = FALSE} knitr::opts_chunk$set(collapse = TRUE, comment = "#>", fig.width = 7, fig.height = 4) ``` ```{r} library(foresightr) path <- system.file("extdata", "piaui_revenue.csv", package = "foresightr") data <- read.csv(path, comment.char = "#") icms <- ts(data$icms / 1e6, start = c(2017, 3), frequency = 12) ``` External information enters a model in three ways: as regressors of an ARIMA model, as a price index that deflates a log-linear regression, and as dated events of a Prophet-style model. Regressors and events must also cover the periods to be forecast; asking for a forecast beyond them is an error. ## Regression with ARIMA errors Tax revenue follows prices. With the log of a price index as a regressor, the errors of the regression follow an ARIMA model, and both are estimated together. Here the model is fitted on the first 100 months, so that the index covers the 12 months forecast. ```{r} model <- model_arima(c(0, 1, 1), c(0, 1, 1), regressors = data.frame(ipca = log(data$ipca_index))) fit <- fit_model(model, log(window(icms, end = time(icms)[100]))) fit$details$regression exp(predict(fit, 6)) ``` The same `regressors` argument is taken by `model_arima()` and `model_auto_arima()`, as a data frame, a matrix or a named list with one row per period from the first observation on. ## Fourier terms Sine and cosine pairs describe a seasonal pattern with few parameters, and the period need not be a whole number. `fourier_terms()` gives them for as many rows as needed: ```{r} y <- log(AirPassengers) x <- fourier_terms(12, 3, length(y) + 12) fit <- fit_model(model_arima(c(1, 1, 1), constant = TRUE, regressors = x), y) names(fit$details$regression) round(exp(predict(fit, 12))) ``` `seasonal_dummies()` gives one dummy per season instead; combine sets of regressors with `cbind()`. ## A deflated regression `model_log_linear(deflator = )` fits trend and seasonality on the deflated series. The future of the index is not needed: the forecasts are inflated back at the growth of the index over the last twelve months. ```{r} deflated <- model_log_linear(deflator = data$ipca_index) fit <- fit_model(deflated, icms) fit$params[c("trend_growth_pct", "inflation_pct")] predict(fit, 6) ``` ## Events and steps A Prophet-style model takes events, which happen at given positions (counted from 1 at the first observation, future ones included), and steps, lasting changes of level from a position on. Their effects are estimated with the trend and seasonality. ```{r} set.seed(1) t <- 1:120 sales <- 200 + 0.8 * t + 5 * sin(2 * pi * t / 12) + rnorm(120, sd = 2) campaigns <- c(11, 35, 59, 83, 107) sales[campaigns] <- sales[campaigns] + 20 # a campaign every other November sales[t >= 81] <- sales[t >= 81] - 15 # a new law cuts the level sales <- ts(sales, frequency = 12) model <- model_prophet(changepoints = 0, events = list(campaign = c(campaigns, 131)), steps = list(new_law = 81)) fit <- fit_model(model, sales) round(fit$details$effects, 1) ``` The effects come out close to the +20 and -15 put in, and the forecast includes the campaign planned for position 131.