## ----config, include = FALSE--------------------------------------------------
# Change default location and time
Sys.setlocale("LC_TIME", "C")

knitr::opts_chunk$set(
  collapse = TRUE,
  comment = "#>",
  fig.height = 5,
  fig.width = 7
)

## ----packages, message = FALSE, warning = FALSE-------------------------------
library(echos)
library(tidyverse)
library(tsibble)
library(fable)

## ----data---------------------------------------------------------------------
selected_series <- c("M21655", "M2717")

data_frame <- m4_monthly_subset %>%
  filter(series %in% selected_series)

data_frame

## ----data-plot, fig.alt = "Monthly observations for two M4 time series"-------
p <- ggplot()

p <- p + geom_line(
  data = data_frame,
  aes(
    x = index,
    y = value),
  linewidth = 0.5
)

p <- p + facet_wrap(
  vars(series),
  ncol = 1,
  scales = "free_y"
)

p <- p + labs(
  x = "Time",
  y = "Value"
)

p

## ----setup--------------------------------------------------------------------
n_train <- 180
n_ahead <- 18
n_step <- 1
n_splits <- 5

n_required <- n_train + n_ahead + (n_splits - 1) * n_step

## ----analysis-data------------------------------------------------------------
analysis_frame <- data_frame %>%
  group_by_key() %>%
  slice_tail(n = n_required) %>%
  ungroup()

analysis_frame

## ----rolling-windows----------------------------------------------------------
train_frame <- analysis_frame %>%
  slide_tsibble(
    .size = n_train,
    .step = n_step,
    .id = "split"
  ) %>%
  filter(split <= n_splits)

train_frame

## ----split-summary------------------------------------------------------------
split_frame <- train_frame %>%
  as_tibble() %>%
  summarise(
    train_start = min(index),
    train_end = max(index),
    n = n(),
    .by = c(series, split)
  )

split_frame

## ----models-------------------------------------------------------------------
model_frame <- train_frame %>%
  model(
    "ESN" = ESN(value)
  )

model_frame

## ----forecasts----------------------------------------------------------------
fable_frame <- model_frame %>%
  forecast(h = n_ahead)

fable_frame

## ----accuracy-----------------------------------------------------------------
accuracy_frame <- fable_frame %>%
  accuracy(data = analysis_frame)

accuracy_frame

## ----forecast-data------------------------------------------------------------
forecast_frame <- fable_frame %>%
  as_tibble() %>%
  transmute(
    series,
    split,
    index,
    FORECAST = .mean
  )

plot_frame <- forecast_frame %>%
  left_join(
    analysis_frame %>%
      as_tibble() %>%
      select(
        series,
        index,
        ACTUAL = value),
    by = c(
      "series",
      "index")) %>%
  pivot_longer(
    cols = c(ACTUAL, FORECAST),
    names_to = "type",
    values_to = "value"
    )

plot_frame

## ----forecast-plot, fig.width = 10, fig.height = 6, fig.alt = "Rolling forecasts and actual values for two M4 monthly time series"----
p <- ggplot()

p <- p + geom_line(
  data = plot_frame,
  aes(
    x = index,
    y = value,
    color = type),
  linewidth = 0.6
)

p <- p + facet_grid(
  rows = vars(series),
  cols = vars(split),
  scales = "free_y"
)

p <- p + scale_color_manual(
  values = c(
    "ACTUAL" = "grey35",
    "FORECAST" = "steelblue"
  )
)

p <- p + labs(
  title = "Rolling forecasts for M4 monthly time series",
  subtitle = "Fixed 180-month training windows and an 18-month forecast horizon",
  x = "Time",
  y = "Value",
  color = NULL
)

p <- p + theme(legend.position = "top")

p

