| Title: | Tools for Seasonal Adjustment Diagnostics and Reporting |
|---|---|
| Description: | Provides tools for automated diagnostics, model selection and reporting for seasonal adjustment based on X-13ARIMA-SEATS. Wraps the 'seasonal' package to run and compare alternative specifications, extract quality indicators and residual diagnostics, and generate reproducible R Markdown reports for official statistics and other production workflows. |
| Authors: | Philipp Wegmüller [aut, cre] (ORCID: <https://orcid.org/0000-0001-7122-5838>) |
| Maintainer: | Philipp Wegmüller <[email protected]> |
| License: | MIT + file LICENSE |
| Version: | 0.1.0 |
| Built: | 2026-09-14 23:20:53 UTC |
| Source: | https://github.com/p-wegmueller/seasight |
Runs a grid of X-13ARIMA-SEATS specifications, computes diagnostics
(QS tests, residual checks, revision metrics, distance to a baseline
model, etc.), and ranks candidates using a composite score. Returns
the best model together with a diagnostic table and seasonality call.
The function may fit several X-13 models; use max_specs for fast
exploratory runs and larger grids for review runs.
auto_seasonal_analysis( y, specs = NULL, use_fivebest = TRUE, max_specs = NULL, seasonal_only = TRUE, auto_outliers = TRUE, transform_fun = c("auto", "log", "none"), td_candidates = NULL, td_usertype = "td", include_easter = c("auto", "always", "off"), easter_len = 15L, include_history_top_n = 10, early_period_end = NULL, current_model = NULL, current_sa = NULL, current_seasonal = NULL, w_qs = 1, w_stability = 1, w_aicc = 1, w_rev = 0.5, w_dist_sa = 1, w_dist_seas = 0.5, w_engine = 1, engine = c("seats", "x11", "auto"), outlier_types = c("AO", "LS", "TC"), outlier_method = "AddOne", outlier_critical = 4, outlier_alpha = NULL, comparison_mode = c("full_search", "incumbent_fixed") )auto_seasonal_analysis( y, specs = NULL, use_fivebest = TRUE, max_specs = NULL, seasonal_only = TRUE, auto_outliers = TRUE, transform_fun = c("auto", "log", "none"), td_candidates = NULL, td_usertype = "td", include_easter = c("auto", "always", "off"), easter_len = 15L, include_history_top_n = 10, early_period_end = NULL, current_model = NULL, current_sa = NULL, current_seasonal = NULL, w_qs = 1, w_stability = 1, w_aicc = 1, w_rev = 0.5, w_dist_sa = 1, w_dist_seas = 0.5, w_engine = 1, engine = c("seats", "x11", "auto"), outlier_types = c("AO", "LS", "TC"), outlier_method = "AddOne", outlier_critical = 4, outlier_alpha = NULL, comparison_mode = c("full_search", "incumbent_fixed") )
y |
A time series ( |
specs |
Optional character vector of ARIMA specifications in the
form |
use_fivebest |
Logical. If |
max_specs |
Optional positive integer limiting the number of candidate ARIMA specifications fitted after de-duplication and seasonal filtering. |
seasonal_only |
Logical. If |
auto_outliers |
Logical. If |
transform_fun |
Transformation applied to the input series before
seasonal adjustment. |
td_candidates |
Optional named list of alternative trading-day
regressors, e.g. |
td_usertype |
Character string passed as |
include_easter |
Controls inclusion of Easter regressors:
|
easter_len |
Integer, length (in days) of the Easter effect imposed by
|
include_history_top_n |
Integer, number of top-ranked models for which revision metrics over the history are computed before the final ranking step. |
early_period_end |
Reserved for future use. Optional index or date marking the end of an early sample period used for stability checks. |
current_model |
Optional incumbent |
current_sa |
Optional baseline seasonally adjusted series. If not
supplied, it is extracted from |
current_seasonal |
Optional baseline seasonal component. If not
supplied, it is extracted from |
w_qs |
Weight of the QS (seasonality) diagnostics in the composite ranking score. |
w_stability |
Weight of residual / stability diagnostics (e.g. Ljung-Box) in the composite score. |
w_aicc |
Weight of the information criterion (AICc) in the composite score. |
w_rev |
Weight of the revision metric (historical revision MAE) in the composite score. |
w_dist_sa |
Weight of the distance between seasonally adjusted series (candidate vs baseline) in the composite score. |
w_dist_seas |
Weight of the distance between seasonal components (candidate vs baseline) in the composite score. |
w_engine |
Weight / penalty term related to the decomposition engine (SEATS vs X-11) in the composite score. |
engine |
Engine preference for candidate models. One of
|
outlier_types |
Character vector of outlier types to detect,
typically a subset of |
outlier_method |
Character scalar giving the outlier detection
method (passed to |
outlier_critical |
Numeric critical value for outlier detection (e.g. t- or z-threshold). |
outlier_alpha |
Optional numeric significance level for outlier
detection. If supplied, it is converted to a two-sided normal cutoff
for |
comparison_mode |
Comparison design. |
Ranking combines residual seasonality on the adjusted series (QS_p),
Ljung-Box residual diagnostics, AICc, revision metrics for the top
candidates, distance from an incumbent model when supplied, and a small
engine-preference penalty.
An object of class "auto_seasonal_analysis" with components
such as best (best seas model), table (diagnostic and ranking
table, including actual Easter inclusion in with_easter and its selected
window in easter_window, SEATS substitution metadata in
SEATS_model_switch and SEATS_operative_model, and peak-to-trough
seasonal amplitude in seasonal_amp_pct. For log models this is the
seasonal-factor range in percentage points; for level models it is the
additive range relative to the median absolute series level), specs_tried,
frequency, transform, baseline, and
seasonality. When current_model is supplied, baseline includes its
diagnostics and an indicator of whether its AICc is comparable with the
selected candidate. comparison_mode and regressor_comparison describe
whether candidate AICc differences hold the incumbent regressors fixed.
if (requireNamespace("seasonal", quietly = TRUE)) { res <- auto_seasonal_analysis( AirPassengers, max_specs = 3, include_history_top_n = 2 ) res$seasonality$overall }if (requireNamespace("seasonal", quietly = TRUE)) { res <- auto_seasonal_analysis( AirPassengers, max_specs = 3, include_history_top_n = 2 ) res$seasonality$overall }
Helper to create generic calendar regressors without relying on any country-specific datasets shipped with the package. This is deliberate: production holiday calendars should usually come from an authoritative institutional source, not from a generic package dataset.
build_user_xreg( y, td_candidates = NULL, holidays = NULL, frequency = NULL, td_usertype = "holiday", default_center = c("calendar", "mean", "none") )build_user_xreg( y, td_candidates = NULL, holidays = NULL, frequency = NULL, td_usertype = "holiday", default_center = c("calendar", "mean", "none") )
y |
A |
td_candidates |
Optional named list of precomputed regressors (ts-boxable). |
holidays |
Optional list defining moving-holiday regressors. Each element may be:
|
frequency |
Optional frequency to use for holiday regressors (defaults to |
td_usertype |
X-13 usertype label for all returned regressors (default "holiday"). |
default_center |
Default centering for holiday regressors. |
Supports:
Precomputed regressors (td_candidates): named list of ts-boxable series
Moving-holiday regressors (holidays): built via seasonal::genhol()
The output is directly consumable by auto_seasonal_analysis() via its
td_candidates argument.
A named list of ts regressors aligned to y. Attribute td_usertype
is attached for downstream use.
diwali_dates <- as.Date(c("2022-10-24", "2023-11-12", "2024-11-01")) xreg <- build_user_xreg( y = AirPassengers, holidays = list(diwali = list(dates = diwali_dates, start = -1, end = 1)), td_usertype = "holiday" ) names(xreg)diwali_dates <- as.Date(c("2022-10-24", "2023-11-12", "2024-11-01")) xreg <- build_user_xreg( y = AirPassengers, holidays = list(diwali = list(dates = diwali_dates, start = -1, end = 1)), td_usertype = "holiday" ) names(xreg)
seas modelExtract X-13 outlier coefficients (AO/LS/TC) from a seas model
extract_outliers(m)extract_outliers(m)
m |
A fitted seasonal::seas model. |
A tibble with columns type, period, coef. Empty when none found.
if (requireNamespace("seasonal", quietly = TRUE)) { m <- seasonal::seas(AirPassengers) extract_outliers(m) }if (requireNamespace("seasonal", quietly = TRUE)) { m <- seasonal::seas(AirPassengers) extract_outliers(m) }
Provides a compact default plot for the main result class returned by
auto_seasonal_analysis(). The plot is intended for quick inspection; the
HTML report remains the richer review artifact.
## S3 method for class 'auto_seasonal_analysis' plot( x, series = c("final", "seasonal", "original"), xlab = "time", ylab = NULL, ... )## S3 method for class 'auto_seasonal_analysis' plot( x, series = c("final", "seasonal", "original"), xlab = "time", ylab = NULL, ... )
x |
An object returned by |
series |
Which series to show. |
xlab, ylab
|
Axis labels. |
... |
Additional arguments passed to |
Invisibly, x.
if (requireNamespace("seasonal", quietly = TRUE)) { res <- auto_seasonal_analysis(AirPassengers, max_specs = 3) plot(res) }if (requireNamespace("seasonal", quietly = TRUE)) { res <- auto_seasonal_analysis(AirPassengers, max_specs = 3) plot(res) }
Convenience helper for reproducing a problematic single series. It writes an HTML report and returns the normalized output path invisibly.
probe_case( y, outfile = tempfile("seasight-probe-", fileext = ".html"), verbose = TRUE, report_fun = sa_report_html, ... )probe_case( y, outfile = tempfile("seasight-probe-", fileext = ".html"), verbose = TRUE, report_fun = sa_report_html, ... )
y |
Series to analyse. |
outfile |
Output HTML path. Defaults to a temporary file. |
verbose |
If |
report_fun |
Report function. Defaults to |
... |
Additional arguments passed to |
Invisibly, the normalized output path.
fake_report <- function(y, outfile, ...) { writeLines("<html><body>probe</body></html>", outfile) list(report = outfile) } probe_case( y = AirPassengers, outfile = tempfile("probe-", fileext = ".html"), verbose = FALSE, report_fun = fake_report )fake_report <- function(y, outfile, ...) { writeLines("<html><body>probe</body></html>", outfile) list(report = outfile) } probe_case( y = AirPassengers, outfile = tempfile("probe-", fileext = ".html"), verbose = FALSE, report_fun = fake_report )
Standardizes user-supplied regressors before they are passed to X-13. The
helper checks frequency, windows the regressor to the span of y, and returns
NULL if the result cannot be aligned exactly.
sa_align_regressor(y, x)sa_align_regressor(y, x)
y |
Target series, coercible to |
x |
Regressor series, coercible to |
A ts object aligned to y, or NULL when alignment fails.
y <- AirPassengers x <- stats::lag(y, -1) aligned <- sa_align_regressor(y, x) stats::frequency(aligned)y <- AirPassengers x <- stats::lag(y, -1) aligned <- sa_align_regressor(y, x) stats::frequency(aligned)
Sequential batch runner with per-series status rows and a structured CSV log.
Existing outputs can be skipped via resume = TRUE.
sa_batch_run( series, out_dir = "sa_reports", ids = NULL, resume = TRUE, timeout = Inf, report_fun = sa_report_html, log_file = NULL, ... )sa_batch_run( series, out_dir = "sa_reports", ids = NULL, resume = TRUE, timeout = Inf, report_fun = sa_report_html, log_file = NULL, ... )
series |
A |
out_dir |
Directory where HTML reports and |
ids |
Optional character vector of IDs, same length as |
resume |
If |
timeout |
Per-series timeout in seconds. Use |
report_fun |
Report function to call per item. Defaults to |
log_file |
Optional CSV log path. Defaults to |
... |
Additional arguments passed to |
A tibble with one row per series: id, ok, status, reason,
message, outfile, and elapsed_seconds.
fake_report <- function(y, outfile, ...) { writeLines("<html><body>ok</body></html>", outfile) list(report = outfile) } out <- sa_batch_run( series = list(series1 = AirPassengers), out_dir = tempdir(), report_fun = fake_report ) out$statusfake_report <- function(y, outfile, ...) { writeLines("<html><body>ok</body></html>", outfile) list(report = outfile) } out <- sa_batch_run( series = list(series1 = AirPassengers), out_dir = tempdir(), report_fun = fake_report ) out$status
Summarises the incumbent current_model against the best model stored in an
auto_seasonal_analysis() result. The comparison is intentionally compact:
it reports key diagnostics, the switching decision from sa_should_switch(),
and aligned seasonally adjusted and seasonal-component series when they are
available.
sa_compare(res, current_model)sa_compare(res, current_model)
res |
Result from |
current_model |
A fitted |
A list of class "seasight_sa_compare" with elements:
decision, summary, series, diagnostics, and table. The decision
uses the incumbent-relative rule documented in sa_should_switch().
if (requireNamespace("seasonal", quietly = TRUE)) { current_model <- seasonal::seas(AirPassengers) res <- auto_seasonal_analysis( y = AirPassengers, current_model = current_model, max_specs = 3 ) sa_compare(res, current_model) }if (requireNamespace("seasonal", quietly = TRUE)) { current_model <- seasonal::seas(AirPassengers) res <- auto_seasonal_analysis( y = AirPassengers, current_model = current_model, max_specs = 3 ) sa_compare(res, current_model) }
SEATS (default engine) -> omit x11/seats args
X-11 -> include x11 = ""
sa_copyable_call( m, x_expr, xreg_expr = NA, include_force = FALSE, engine = c("auto", "seats", "x11") )sa_copyable_call( m, x_expr, xreg_expr = NA, include_force = FALSE, engine = c("auto", "seats", "x11") )
m |
Fitted |
x_expr |
Character code for |
xreg_expr |
|
include_force |
Logical; if TRUE adds |
engine |
|
A single string containing the seas(...) call.
if (requireNamespace("seasonal", quietly = TRUE)) { m <- seasonal::seas(AirPassengers) sa_copyable_call(m, x_expr = "AirPassengers") }if (requireNamespace("seasonal", quietly = TRUE)) { m <- seasonal::seas(AirPassengers) sa_copyable_call(m, x_expr = "AirPassengers") }
Explains, in plain language, why the selected engine was chosen for the best model.
sa_engine_choice_card(res)sa_engine_choice_card(res)
res |
Object from |
An htmltools tag (card).
if (requireNamespace("seasonal", quietly = TRUE)) { res <- auto_seasonal_analysis(AirPassengers, max_specs = 3) sa_engine_choice_card(res) }if (requireNamespace("seasonal", quietly = TRUE)) { res <- auto_seasonal_analysis(AirPassengers, max_specs = 3) sa_engine_choice_card(res) }
Uses IDS, M7 (strong/weak), QS on SA, and QS on ORIGINAL (QSori) to form a simple majority-style decision. Thresholds mirror those used elsewhere.
sa_existence_call( tbl, majority = 0.6, thr = list(qs = 0.1, m7_strong = 0.9, m7_weak = 1.05, borderline_min_share = 0.4, use_qsori = TRUE) )sa_existence_call( tbl, majority = 0.6, thr = list(qs = 0.1, m7_strong = 0.9, m7_weak = 1.05, borderline_min_share = 0.4, use_qsori = TRUE) )
tbl |
Candidate table (e.g., |
majority |
Required share for a positive overall call (default 0.6). |
thr |
List of thresholds: |
A tibble with call_overall and shares per test family.
tbl <- tibble::tibble( QS_p = c(0.04, 0.20, 0.08), M7 = c(0.82, 1.10, 0.95), IDS = c("yes", "no", "yes"), QSori_p = c(0.03, 0.15, 0.07) ) sa_existence_call(tbl)tbl <- tibble::tibble( QS_p = c(0.04, 0.20, 0.08), M7 = c(0.82, 1.10, 0.95), IDS = c("yes", "no", "yes"), QSori_p = c(0.03, 0.15, 0.07) ) sa_existence_call(tbl)
Uses IDS, M7, QS on original, and presence/absence of a SEATS seasonal component to provide a short textual assessment of seasonality for the best model.
sa_existence_card(res)sa_existence_card(res)
res |
Result of |
An htmltools tag representing the card.
if (requireNamespace("seasonal", quietly = TRUE)) { res <- auto_seasonal_analysis(AirPassengers, max_specs = 3) sa_existence_card(res) }if (requireNamespace("seasonal", quietly = TRUE)) { res <- auto_seasonal_analysis(AirPassengers, max_specs = 3) sa_existence_card(res) }
Delegates to the internal .do_not_adjust() to keep logic in one place.
sa_is_do_not_adjust(row)sa_is_do_not_adjust(row)
row |
One-row tibble from |
The weak-amplitude threshold is one percentage point of peak-to-trough seasonal amplitude. For log models, the amplitude is the seasonal-factor range multiplied by 100. For level models, it is the additive seasonal range relative to the median absolute series level.
TRUE if the row satisfies the "do not adjust" rule, FALSE otherwise.
row <- tibble::tibble( IDS = "no", M7 = 1.10, QSori_p_x11 = 0.12, QSori_p_seats = 0.15, SEATS_has_seasonal = FALSE, seasonal_amp_pct = 0.8, vola_reduction_pct = 2 ) sa_is_do_not_adjust(row)row <- tibble::tibble( IDS = "no", M7 = 1.10, QSori_p_x11 = 0.12, QSori_p_seats = 0.15, SEATS_has_seasonal = FALSE, seasonal_amp_pct = 0.8, vola_reduction_pct = 2 ) sa_is_do_not_adjust(row)
User-facing wrapper that runs the automatic seasonal analysis and writes a
human-readable HTML report with plots, tables, diagnostics, and
copy-pasteable seas() calls.
The report fits the same candidate grid as auto_seasonal_analysis() and
can therefore take noticeable time on broad grids. Use max_specs for quick
exploratory reports.
sa_report_html( y, current_model = NULL, td_usertype = "td", td_candidates = NULL, use_fivebest = TRUE, max_specs = NULL, seasonal_only = TRUE, title = "Seasonal Adjustment Report", outfile = "sa_report.html", file = NULL, png_width = 1400, png_height = 900, print_to_console = FALSE, print_which = c("new", "current", "both"), include_easter = c("auto", "always", "off"), easter_len = 15L, engine = c("seats", "x11", "auto"), w_engine = 1, outlier_types = c("AO", "LS", "TC"), outlier_method = "AddOne", outlier_critical = 4, outlier_alpha = NULL, comparison_mode = c("full_search", "incumbent_fixed") )sa_report_html( y, current_model = NULL, td_usertype = "td", td_candidates = NULL, use_fivebest = TRUE, max_specs = NULL, seasonal_only = TRUE, title = "Seasonal Adjustment Report", outfile = "sa_report.html", file = NULL, png_width = 1400, png_height = 900, print_to_console = FALSE, print_which = c("new", "current", "both"), include_easter = c("auto", "always", "off"), easter_len = 15L, engine = c("seats", "x11", "auto"), w_engine = 1, outlier_types = c("AO", "LS", "TC"), outlier_method = "AddOne", outlier_critical = 4, outlier_alpha = NULL, comparison_mode = c("full_search", "incumbent_fixed") )
y |
Time series to be analysed. Can be a |
current_model |
Optional incumbent |
td_usertype |
Character string passed as |
td_candidates |
Optional named list of trading-day candidate regressors
(e.g. |
use_fivebest |
Logical. If |
max_specs |
Optional positive integer limiting the number of candidate ARIMA specifications fitted. |
seasonal_only |
Logical. If |
title |
Title of the report shown in the HTML page. |
outfile |
Path to the HTML file to be written. |
file |
Optional alias for |
png_width, png_height
|
Width and height (in pixels) of PNG plots embedded in the report. |
print_to_console |
Logical. If |
print_which |
Which code blocks to print when |
include_easter |
Controls inclusion of Easter regressors:
|
easter_len |
Integer, length (in days) of the Easter effect imposed by
|
engine |
Preferred decomposition engine for candidate models.
One of |
w_engine |
Numeric weight for the engine choice component in the composite ranking score. |
outlier_types |
Character vector of outlier types to detect, typically
a subset of |
outlier_method |
Character scalar giving the outlier detection method
passed to |
outlier_critical |
Numeric critical value for outlier detection (e.g. a t-/z-threshold). |
outlier_alpha |
Optional numeric significance level; if supplied, it is
converted to a two-sided normal cutoff for |
comparison_mode |
Comparison design passed to
|
Notes:
If the provided current specification equals the selected best model, the report omits the "Alternative model" comparison section.
A reported SEATS model substitution is highlighted in both the summary and engine-choice cards, with requested and operative models when known.
The "Top candidates" table starts with the best model and always includes the current model (flagged as current) when one is supplied.
Invisibly, a list with elements report (path to the HTML file) and
res (the corresponding auto_seasonal_analysis() result).
auto_seasonal_analysis(), sa_existence_card(), sa_top_candidates_table()
if (requireNamespace("seasonal", quietly = TRUE)) { sa_report_html( y = AirPassengers, outfile = tempfile(fileext = ".html"), max_specs = 3 ) }if (requireNamespace("seasonal", quietly = TRUE)) { sa_report_html( y = AirPassengers, outfile = tempfile(fileext = ".html"), max_specs = 3 ) }
Compares the first row of res$table with the incumbent model recorded by
auto_seasonal_analysis(). The candidate must improve comparable AICc by a
material amount, pass absolute residual diagnostics, avoid material
deterioration relative to the incumbent, and satisfy the existing distance
and seasonal-correlation safeguards. Identical adjusted series are kept.
sa_should_switch( res, thresholds = list(min_qs_p = 0.1, max_dist_sa_mult = 1.25, min_corr_seas = 0.9, min_lb_p = 0.05, min_delta_aicc = 2, max_qs_p_drop = 0.05, max_lb_p_drop = 0.05, identical_sa_tolerance = 1e-08), current_model = NULL, details = FALSE )sa_should_switch( res, thresholds = list(min_qs_p = 0.1, max_dist_sa_mult = 1.25, min_corr_seas = 0.9, min_lb_p = 0.05, min_delta_aicc = 2, max_qs_p_drop = 0.05, max_lb_p_drop = 0.05, identical_sa_tolerance = 1e-08), current_model = NULL, details = FALSE )
res |
Result of |
thresholds |
Named list with decision thresholds:
|
current_model |
Optional fitted |
details |
Logical. If |
One of "CHANGE_TO_NEW_MODEL", "KEEP_CURRENT_MODEL",
"REVIEW_REQUIRED", or "NO_BASELINE"; with details = TRUE, a
structured list containing the decision and its supporting evidence.
if (requireNamespace("seasonal", quietly = TRUE)) { current_model <- seasonal::seas(AirPassengers) res <- auto_seasonal_analysis( AirPassengers, current_model = current_model, max_specs = 3 ) sa_should_switch(res) }if (requireNamespace("seasonal", quietly = TRUE)) { current_model <- seasonal::seas(AirPassengers) res <- auto_seasonal_analysis( AirPassengers, current_model = current_model, max_specs = 3 ) sa_should_switch(res) }
Returns M7, IDS, QS on SA (X-11 & SEATS, plus overall min), QS on original (X-11 & SEATS, plus overall min), and Ljung-Box p-value on residuals.
sa_tests_model(m)sa_tests_model(m)
m |
A fitted seasonal::seas object. |
Columns:
M7, IDS
QS_p_x11, QS_p_seats, QS_p (QS on SA)
QSori_p_x11, QSori_p_seats, QSori_p (QS on original)
LB_p
For backwards compatibility, the output also includes the legacy aliases
QS_SA_x11, QS_SA_seats, QS_SA, QSori_x11, QSori_seats, QSori.
A one-row tibble with the diagnostics above.
if (requireNamespace("seasonal", quietly = TRUE)) { m <- seasonal::seas(AirPassengers) sa_tests_model(m) }if (requireNamespace("seasonal", quietly = TRUE)) { m <- seasonal::seas(AirPassengers) sa_tests_model(m) }
Build a colour-coded HTML table of the highest-ranked candidate models,
always placing the best model at the top and including the current
model (if supplied) even if it is not in the top n. The airline
reference model ARIMA (0 1 1)(0 1 1) is also appended if absent.
sa_top_candidates_table(res, current_model = NULL, y = NULL, n = 5)sa_top_candidates_table(res, current_model = NULL, y = NULL, n = 5)
res |
Result of |
current_model |
Optional fitted seasonal::seas model to mark as "current". |
y |
Optional original series (needed to compute a few current-model diagnostics). |
n |
Number of top rows to display (default 5). The airline/current rows
may be appended even if not in the top |
Rows are lightly shaded: best (green), current (blue), airline (red). The
table reports the requested ARIMA, the operative SEATS model when available,
and a stable yes/no/n/a SEATS-switch indicator.
An htmltools tag (<table>) you can insert into reports.
if (requireNamespace("seasonal", quietly = TRUE)) { current_model <- seasonal::seas(AirPassengers) res <- auto_seasonal_analysis( y = AirPassengers, current_model = current_model, max_specs = 3 ) sa_top_candidates_table(res, current_model = current_model, y = AirPassengers, n = 5) }if (requireNamespace("seasonal", quietly = TRUE)) { current_model <- seasonal::seas(AirPassengers) res <- auto_seasonal_analysis( y = AirPassengers, current_model = current_model, max_specs = 3 ) sa_top_candidates_table(res, current_model = current_model, y = AirPassengers, n = 5) }