No supported way to reuse fixed ARIMA orders with regressors under refitting / CV
Nobody has claimed this yet.
- Dominant language
- R
- Stars
- 588
- Forks
- 71
- Avg merge
- 1h 58m
- Merged PRs (30d)
- 1
Description
TL;DR:
fable allows extracting ARIMA orders programmatically but provides no supported, reliable way to reapply those orders when refitting models with regressors (e.g., under expanding‑window CV), since pdq()/PDQ() work only as inline syntax and are not stable for reuse.
Title
No supported way to reuse fixed ARIMA orders with regressors under refitting / CV
Body
Summary
I am trying to fit ARIMA‐with‐regression models where the ARIMA orders are identified once and then reused across refits (e.g., expanding‑window CV or production retraining). While fable allows programmatic extraction of ARIMA orders, there appears to be no supported, stable way to reapply those orders when models include regressors and are refit on new data.
The attached reprex demonstrates this.
library(tidyverse)
library(fable)
#> Loading required package: fabletools
library(tsibble)
#>
#> Attaching package: 'tsibble'
#> The following object is masked from 'package:lubridate':
#>
#> interval
#> The following objects are masked from 'package:base':
#>
#> intersect, setdiff, union
set.seed(123)
# 1. Data with exogenous regressor
df <- tsibble(
date = yearquarter("2000 Q1") + 0:39,
y = rnorm(40),
x = factor(rep(c("A", "B"), length.out = 40)),
index = date
)
# 2. Identification fit (automatic ARIMA)
id_train <- df %>% filter(date <= yearquarter("2008 Q4"))
id_fit <- id_train %>%
model(auto = ARIMA(y ~ x))
id_fit
#> # A mable: 1 x 1
#> auto
#> <model>
#> 1 <LM w/ ARIMA(0,0,1)(1,0,0)[4] errors>
# 3. Extract ARIMA orders programmatically
orders_tbl <- id_fit %>%
pivot_longer(everything(), names_to = "model", values_to = "fit") %>%
as_tibble() %>%
mutate(
orders = map_dfr(
fit,
\(m) m$fit$spec %>%
select(p, d, q, P, D, Q, period, constant)
)
) %>%
select(orders) %>%
unnest_wider(orders)
orders_tbl
#> # A tibble: 1 × 8
#> p d q P D Q period constant
#> <int> <int> <int> <int> <int> <int> <dbl> <lgl>
#> 1 0 0 1 1 0 0 4 FALSE
# 4. Attempt to reconstruct a fixed-order ARIMA model
# using pdq() programmatically
fixed_model <- ARIMA(
y ~ x +
pdq(
orders_tbl$p[[1]],
orders_tbl$d[[1]],
orders_tbl$q[[1]]
) +
PDQ(
orders_tbl$P[[1]],
orders_tbl$D[[1]],
orders_tbl$Q[[1]],
period = orders_tbl$period[[1]]
)
)
# 5. Refit on the SAME data (still works)
df %>%
model(reused = fixed_model) %>%
forecast(
new_data = df %>% slice_tail(n = 4)
)
#> # A fable: 4 x 5 [1Q]
#> # Key: .model [1]
#> .model date
#> <chr> <qtr>
#> 1 reused 2009 Q1
#> 2 reused 2009 Q2
#> 3 reused 2009 Q3
#> 4 reused 2009 Q4
#> # ℹ 3 more variables: y <dist>, .mean <dbl>, x <fct>
# 6. Refit on a DIFFERENT training window (CV semantics)
new_train <- df %>% filter(date <= yearquarter("2006 Q4"))
future_x <- new_train %>%
new_data(n = 4) %>%
mutate(
x = factor("A", levels = levels(df$x))
)
new_train %>%
model(reused = fixed_model) %>%
forecast(new_data = future_x)
#> Warning: It looks like you're trying to fully specify your ARIMA model but have not said
#> if a constant should be included. You can include a constant using `ARIMA(y~1)`
#> to the formula or exclude it by adding `ARIMA(y~0)`.
#> Warning: 1 error encountered for reused
#> [1] Could not find an appropriate ARIMA model.
#> This is likely because automatic selection does not select models with characteristic roots that may be numerically unstable.
#> For more details, refer to https://otexts.com/fpp3/arima-r.html#plotting-the-characteristic-roots
#> # A fable: 4 x 5 [1Q]
#> # Key: .model [1]
#> .model date y .mean x
#> <chr> <qtr> <dist> <dbl> <fct>
#> 1 reused 2007 Q1 NA NA A
#> 2 reused 2007 Q2 NA NA A
#> 3 reused 2007 Q3 NA NA A
#> 4 reused 2007 Q4 NA NA A
Created on 2026-03-28 with reprex v2.1.1
Observed behavior
In the reprex:
- An automatic ARIMA model with an exogenous regressor is fit successfully.
- The ARIMA orders are extracted programmatically from the fitted model.
- A new ARIMA model is constructed using
pdq()/PDQ()with those extracted orders. - Reusing this model on the same training data works.
- Refitting the same stored model on a different training window (CV semantics) fails, producing
NAforecasts and ARIMA identification warnings.
This makes fixed‑order reuse unreliable once refitting is involved.
Key issue
pdq()/PDQ()work as inline formula syntax, but are not stable for programmatic model reuse under refitting.- There is no exported alternative (e.g., a spec object) that allows users to safely freeze and reapply ARIMA orders.
- As a result, a common workflow—identify ARIMA structure once, then reuse it across windows—is not reliably supported.
Expected behavior
One of the following would resolve the issue:
- A documented, exported API for constructing a reusable fixed‑order ARIMA specification (with regressors), or
- Clear documentation stating that
pdq()/PDQ()are not supported for model reuse / CV and cannot be relied upon in this way.
Why this matters
Freezing ARIMA error structure across refits is a standard requirement for:
- expanding‑window cross‑validation
- fair model comparison
- production refitting with fixed structure
Currently, these workflows are brittle or unsupported despite order extraction being possible.
Environment
- R 4.5.3
- fable (CRAN)
- fabletools (CRAN)
- tsibble (CRAN)
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reproducing the reported behavior with ARIMA(), pdq(), PDQ(), model(), and forecast() using the reprex in the issue. Trace how the model specification is stored and reapplied during refitting, then determine whether a reusable fixed-order API or documentation is appropriate; done means fixed orders with regressors work reliably across training windows, or their limitations are clearly documented.
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
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 38/100