knitr::opts_chunk$set(collapse = TRUE, comment = "#>", fig.width = 7, fig.height = 4)
forecastsuite is a local, full-featured companion to the hosted Forecast Dashboard
Shiny app. This vignette covers two ways to use it: the bundled app (run_app()), for
interactive, no-code forecasting, and the underlying model registry, for scripting
forecasts directly in R.
library(forecastsuite) run_app()
run_app() launches a local Shiny app with four tabs, worked in order:
torch is installed), Fit & Forecast, and browse the plot, metrics,
rolling-origin cross-validation, and an Analysis panel: seasonal decomposition,
anomaly detection, residual diagnostics, and (with a grouping column active)
cross-group correlation. A "Show Code" panel prints the R equivalent of whatever you
just ran, with a copy-to-clipboard button and a download.Saving your setup (dataset, holidays, every Model-tab setting) to one file and reloading it later is available from any tab, via "Save Project (.rds)" / "Load Project (.rds)".
Every model -- built-in or your own -- implements the same three-function contract:
fit(train_df, date_agg, ...) # -> model_obj forecast(model_obj, h, ...) # -> raw_forecast_obj to_tibble(raw_forecast_obj, test_df) # -> tibble(ds, yhat[, yhat_lower, yhat_upper])
train_df/test_df are ds/y tibbles (date, value). list_models() lists what's
registered; get_model(key) returns one entry.
library(forecastsuite) vapply(list_models(available_only = TRUE), function(m) m$key, character(1))
set.seed(1) n <- 120 ds <- as.Date("2023-01-01") + 0:(n - 1) y <- 100 + 15 * sin(2 * pi * seq_len(n) / 7) + seq_len(n) * 0.2 + rnorm(n, sd = 3) train_df <- tibble::tibble(ds = ds[1:100], y = y[1:100]) test_df <- tibble::tibble(ds = ds[101:120], y = y[101:120]) model <- get_model("arima") fit_obj <- model$fit(train_df, date_agg = "day", auto = TRUE) fc_raw <- model$forecast(fit_obj, h = 20) fc_tib <- model$to_tibble(fc_raw, test_df) head(fc_tib)
safe_compute_metrics(fc_tib, test_df, label = "Test")
plot_forecast_generic(fc_tib, train_df = train_df, subtitle = model$annotate(fit_obj))
The same functions behind the app's Analysis panel work standalone on any ds/y
tibble -- no fitted model needed for decomposition or anomaly detection, and no Shiny
session either.
decomp <- decompose_series(train_df, date_agg = "day") head(decomp)
anomalies <- detect_anomalies(train_df, date_agg = "day", method = "iqr", threshold = 1.5) anomalies[anomalies$is_anomaly, ]
resid_diag <- compute_residual_diagnostics(fc_tib, test_df) resid_diag[c("ljung_box_p", "shapiro_p", "n")]
group_correlation_matrix() takes a named list of ds/y tibbles (one per group, e.g.
grouped_series() from the app) and returns pairwise correlations:
group_correlation_matrix(list( A = tibble::tibble(ds = ds, y = y), B = tibble::tibble(ds = ds, y = y * 0.5 + rnorm(n, sd = 1)) ))
Adding a model is one register_model() call away from working everywhere the built-in
ones do (the app's Model tab, Compare Models, Cross-Validation, the Show Code panel):
register_model( key = "naive_last", label = "Naive (last value)", fit = function(train_df, date_agg = "day", ...) utils::tail(train_df$y, 1), forecast = function(model_obj, h, ...) list(mean = rep(model_obj, h)), to_tibble = function(fc_obj, test_df) { tibble::tibble(ds = test_df$ds[seq_along(fc_obj$mean)], yhat = fc_obj$mean) } )
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.