seasight provides
tools to see seasonal adjustment more clearly. It wraps the seasonal
interface to X-13ARIMA-SEATS with:
The main target audience are applied economists and official statisticians who need stable, well-documented seasonal adjustment workflows, e.g. in National Accounts or short-term indicators.
The design follows the recommendations in Eurostat’s ESS Guidelines on Seasonal Adjustment and the Handbook on Seasonal Adjustment.(European Commission)
seasight is designed to complement the core seasonal
API.
seasonal::seas() when you need direct
hand-crafted X-13 calls.seasight when you need a standardized and auditable
workflow around those calls (candidate grids, diagnostics, ranking, and
reporting artifacts).In other words, seasight focuses on decision
support and reproducibility in institutional workflows, while
the decomposition engine remains X-13 via seasonal.
We assume that X-13ARIMA-SEATS is available via the
seasonal package (see ?seasonal::seas for
installation details).
seasonalIn production you typically start from a manually maintained X-13 specification. Here we use the very simple default call:
m_current is a regular seasonal::seas
object. seasight does not replace
seasonal – it sits on top and helps you:
sa_tests_model()The basic diagnostic building block is sa_tests_model().
It computes a set of standard tests for a single
seas model:
For the 0.1.x pre-submission cycle, the core user-facing outputs are frozen; typical fields include:
These metrics are the raw ingredients for the higher-level decisions discussed below.
auto_seasonal_analysis()auto_seasonal_analysis() searches over a grid of
candidate X-13 specs and ranks them according to a composite score:
res <- auto_seasonal_analysis(
y = x,
use_fivebest = TRUE,
include_easter = "auto",
td_usertype = "td",
engine = "auto" # let seasight choose between SEATS / X-11
)
names(res)The most important components are:
res$best The best seas model
(a regular seasonal::seas object).
res$table A tibble with one row per candidate,
including:
Typical columns include:
model_label – a short identifier,ARIMA_disp / arima /
spec_id),with_td, td_p – trading-day regressor and
its p-value,QS_p_x11, QS_p_seats, QS_p –
QS on SA,QSori_p_x11, QSori_p_seats,
QSori_p – QS on original,LB_p – Ljung–Box p-value,seasonal_amp_pct – peak-to-trough seasonal amplitude:
the seasonal-factor range in percentage points for log models, or the
additive component range as a percentage of the median absolute series
level for level models,vola_reduction_pct – volatility reduction (%),dist_sa_L1 – L1 distance vs. the current SA (if
supplied),rev_mae – mean absolute revision (if history info is
available),score – the composite score used for ranking.res$seasonality A nested list with an
“existence-of-seasonality” decision for the original series, based on
QS, IDS and M7 (see Eurostat guidelines).(European
Commission)
seasight can compare models without
regressors against models with user-supplied calendar
regressors via td_candidates.
A key design choice: the package does not ship country-specific calendars. Instead you can build generic regressors yourself and pass them in.
# Example: build a Diwali "pulse" regressor (quarterly here, for illustration)
diwali_dates <- as.Date(c(
"2018-11-07","2019-10-27","2020-11-14","2021-11-04",
"2022-10-24","2023-11-12","2024-11-01"
))
td <- build_user_xreg(
y = x,
holidays = list(diwali = list(dates = diwali_dates, start = -1, end = 1)),
td_usertype = "holiday"
)
res_td <- auto_seasonal_analysis(x, td_candidates = td, engine = "auto")For more realistic workflows (multiple TD candidates, baselines, and decision rules), see the SA practice and Advanced vignettes.
The winning model is in res$best:
You can use it like any other seas object:
If you prefer to keep everything explicit, you can access the
underlying specification as R code using sa_copyable_call()
(also shown in the HTML report, see below):
sa_existence_card() and
sa_engine_choice_card()In interactive HTML outputs (e.g. pkgdown site, Quarto, Shiny) it is often helpful to summarise key decisions in compact “cards”.
seasight exposes two such cards:
# Existence-of-seasonality card
sa_existence_card(res)
# Engine choice card (SEATS vs X-11)
sa_engine_choice_card(res)sa_should_switch()If you provide a current (baseline) model,
seasight can suggest whether you should
keep it or switch to the new best
candidate.
res_with_baseline <- auto_seasonal_analysis(
y = x,
current_model = m_current
)
sa_should_switch(res_with_baseline)The decision rule takes into account:
An identical adjustment is kept. If incumbent evidence is missing or
AICc is not comparable because the input sample or transformation
differs, the helper returns "REVIEW_REQUIRED" instead of
recommending a change.
You can always override this decision – the goal is to provide a transparent, reproducible default that is broadly aligned with Eurostat practice (e.g. avoid switching for tiny cosmetic improvements).(European Commission)
sa_report_html()For documentation, review meetings or method reports you often want a self-contained HTML document:
tmp_file <- tempfile(fileext = ".html")
sa_report_html(
y = x,
current_model = m_current,
title = "AirPassengers – seasight demo",
outfile = tmp_file
)
tmp_file
# Browse to this file in your file manager or with browseURL(tmp_file)The report includes:
seas() calls for both specifications,
andFor a deeper dive into:
see the companion vignette:
“Advanced usage: baselines, TD candidates & decision rules”
which uses the same AirPassengers series but goes
further into methodological details.
seasonalsa_tests_model()auto_seasonal_analysis()sa_existence_card() and
sa_engine_choice_card()sa_should_switch()sa_report_html()