tidyverts / tidyverts/fable

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

Open
#441 4 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

question
Dominant language
R
Stars
588
Forks
71
Avg merge
1h 58m
Merged PRs (30d)
1

Description

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

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the reprex in the issue and compare the outputs of augment(), forecast(), and the distributional/vctrs operations used to combine them. Define the intended API and behavior for a continuous fable containing observed and forecasted values, including whether multi-period growth rates are in scope; done means the requested workflow is supported without the manual conversions shown.

Written by the indexing model from the issue text.

Assessment

Tech stack
r
Domain
data
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.