Skip to content

Request for functionality to produce a combined fable of observed and forecasted values #441

@drgomulka

Description

@drgomulka

Some forecasting applications require having a continuous vector of the forecasted variable. This vector needs to combine observed and forecasted values. One such need is to produce estimations of multi-period (e.g. annual) growth rates based on one-period forecasts.

The reprex below illustrates how this can be done for the particular example of tsibble::tourism data. I also made an example on rpubs which illustrates using the combined fable for differencing with a lag.

  • To properly calculate growth rates later, I need the response variable to be log-transformed.
  • In the data from augment() I am replacing observed values with a zero-variance distribution: dist_lognormal( log(Trips), 0)) . I fix the tsibble to be of class fable.
  • Unfortunately forecast() by default returns a fable with a dist_transformed. dist_transformed has no methods to calculate differences between distributions. I decided to replace them with dist_lognormal distributions.
  • I combined both fables.

Those steps took me over a week to develop and are not obvious to a beginner and there is no vignette for that. I had to dig into aspects of distributional and vctrs packages to use the proper functions to get the data out.

Conclusion: There is a need for a function that produces output like a combined output of augment() and forecast(). Maybe functions for the proper calculation of multi-period growth rates could be added too.

library(tsibble)
library(dplyr)
library(fable)
library(vctrs)
library(distributional)

tsb_selected <- tourism |>
  filter(Region %in% c('Adelaide') )  |>
  filter(Purpose %in% c('Business', 'Holiday')  )

fit_selected <- tsb_selected        |>
  model( ets = ETS(log(Trips) ) )

fc_ahead <-  fit_selected |>
  forecast(h = 5)

fc_ahead |>
  group_by_key() |>
  slice_tail(n=3) |>
  knitr::kable()
Region State Purpose .model Quarter Trips .mean
Adelaide South Australia Business ets 2018 Q3 t(N(5.2, 0.057)) 191.2471
Adelaide South Australia Business ets 2018 Q4 t(N(5.1, 0.055)) 169.5137
Adelaide South Australia Business ets 2019 Q1 t(N(5, 0.053)) 147.8054
Adelaide South Australia Holiday ets 2018 Q3 t(N(5.1, 0.021)) 166.4275
Adelaide South Australia Holiday ets 2018 Q4 t(N(5.2, 0.021)) 186.0615
Adelaide South Australia Holiday ets 2019 Q1 t(N(5.3, 0.022)) 212.8007
fable_from_augmented_fit <- fit_selected |>
  augment()  |>
  select(-any_of(c(".innov", ".fitted", ".resid"))) |>
  mutate(Trips =  dist_lognormal(  log(Trips), 0))  |>
  mutate(.mean = mean(Trips))

dimnames(fable_from_augmented_fit$Trips) <- "Trips"

fable_from_augmented_fit <- fable_from_augmented_fit |>
  as_fable(response = "Trips", distribution = "Trips")

fable_from_augmented_fit |>
  group_by_key() |>
  slice_tail(n=3) |>
  knitr::kable()
Region State Purpose .model Quarter Trips .mean
Adelaide South Australia Business ets 2017 Q2 lN(5.2, 0) 173.7364
Adelaide South Australia Business ets 2017 Q3 lN(5.2, 0) 185.3026
Adelaide South Australia Business ets 2017 Q4 lN(5.3, 0) 197.2800
Adelaide South Australia Holiday ets 2017 Q2 lN(5.3, 0) 201.7341
Adelaide South Australia Holiday ets 2017 Q3 lN(5.1, 0) 163.7119
Adelaide South Australia Holiday ets 2017 Q4 lN(5.4, 0) 214.0531
y_as_lnorm <- fc_ahead |>
  pull(Trips)  |>
  vec_data()  |>
  lapply (\(x)  x[[1]] )   |>
  vec_restore( fc_ahead$Trips )    |>
  exp()

fc_as_lnorm <- fc_ahead  |>
  mutate( Trips = y_as_lnorm ) |>
  mutate( .mean = mean(Trips) )

fc_all <- dplyr::bind_rows(fable_from_augmented_fit, fc_as_lnorm)

autoplot(fc_all, level=90)  |> print()

fc_all |>
  group_by_key() |>
  slice_tail(n=3) |>
  knitr::kable()
Region State Purpose .model Quarter Trips .mean
Adelaide South Australia Business ets 2018 Q3 lN(5.2, 0.057) 191.3230
Adelaide South Australia Business ets 2018 Q4 lN(5.1, 0.055) 169.5768
Adelaide South Australia Business ets 2019 Q1 lN(5, 0.053) 147.8564
Adelaide South Australia Holiday ets 2018 Q3 lN(5.1, 0.021) 166.4364
Adelaide South Australia Holiday ets 2018 Q4 lN(5.2, 0.021) 186.0720
Adelaide South Australia Holiday ets 2019 Q1 lN(5.3, 0.022) 212.8133

Created on 2025-12-21 with reprex v2.1.1

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions