New features to come next week
Formula interface with Tables.jl support.
I started with Arima.
Thank you for your suggestions, now Table.jl supported.
I introduce some R dplyr like functions to help R users to be able to us the Durbyn.jl
Durbyn ARIMA Grammar
The Durbyn forecasting grammar lets you describe ARIMA and SARIMA models with a concise,
readable syntax. This guide covers each grammar component and shows how to combine them
when fitting models via ArimaSpec and @formula.
1. Formula Basics
Use the @formula macro to define the relationship between a target series and its
ARIMA structure:
@formula(sales = p() + d() + q())
Every formula must provide a target (left-hand side) and one or more terms on the
right-hand side. Terms may specify ARIMA orders, seasonal orders, exogenous variables,
or automatic-exogenous selection (see below).
2. Non-Seasonal Orders
| Function |
Meaning |
Default or form |
p() |
Non-seasonal AR order |
Search range 2–5 |
p(k) |
Fix AR order |
Uses k exactly |
p(min,max) |
Search AR order range |
Searches min through max |
d() |
Differencing order (auto) |
auto_arima chooses |
d(k) |
Fix differencing order |
Uses k exactly |
q() |
Non-seasonal MA order |
Search range 2–5 |
q(k) |
Fix MA order |
Uses k exactly |
q(min,max) |
Search MA order range |
Searches min through max |
Any range (min,max) triggers full auto_arima search. If all orders are fixed,
the formula interface automatically calls the faster arima routine.
3. Seasonal Orders
Seasonal counterparts include P, D, and Q:
@formula(sales = p() + d() + q() + P() + Q())
| Function |
Meaning |
Default or form |
P() |
Seasonal AR order |
Search range 1–2 |
P(k) |
Fix seasonal AR order |
Uses k exactly |
P(min,max) |
Search seasonal AR order range |
Searches min through max |
D() |
Seasonal differencing (auto) |
auto_arima chooses |
D(k) |
Fix seasonal differencing order |
Uses k exactly |
Q() |
Seasonal MA order |
Search range 1–2 |
Q(k) |
Fix seasonal MA order |
Uses k exactly |
Q(min,max) |
Search seasonal MA order range |
Searches min through max |
Remember to provide the seasonal period m when fitting (fit(spec, data, m=12)).
4. Exogenous Regressors
4.1 Explicit Variables
Add predictors by listing column names:
@formula(sales = p() + q() + price + promotion)
These become VarTerms—during fitting Durbyn pulls the matching columns from your data.
4.2 Automatic Selection (auto())
Use auto() to include all numeric columns except the target, group columns, and
optional date column. Examples:
@formula(sales = auto()) # pure auto ARIMA + automatic xregs
@formula(sales = p() + q() + auto()) # combine with explicit ARIMA orders
Automatic selection is mutually exclusive with explicit exogenous variables or
xreg_formula.
5. Complex Designs (xreg_formula)
For interactions or transformations, supply a secondary formula when constructing
ArimaSpec:
spec = ArimaSpec(
@formula(sales = p() + q()),
xreg_formula = Formula("~ temperature * promotion + price^2")
)
The xreg_formula is evaluated via Utils.model_matrix, producing the necessary
design matrix before fitting.
6. Putting It Together
spec = ArimaSpec(
@formula(sales = p(0,3) + d() + q(0,3) + P() + Q() + auto()),
m = 12,
stepwise = false # passthrough option to auto_arima
)
fitted = fit(spec, panel_data; groupby = [:store], datecol = :date)
Key points:
- Any range triggers automatic model selection.
- Fixed orders call fast direct estimation.
- Exogenous support includes explicit columns,
auto(), or complex formulas.
- Combine with
PanelData to store group/date metadata cleanly.
This grammar provides a declarative, composable way to describe ARIMA/SARIMA models
without manual tuning loops.
7. End-to-End Example (Retail Panel)
using CSV
using Downloads
using Tables
using Durbyn
using Durbyn.TableOps
# Download and reshape data
local_path = Downloads.download(
"https://raw.githubusercontent.com/Akai01/example-time-series-datasets/refs/heads/main/Data/retail.csv"
)
retail = CSV.File(local_path)
tbl = Tables.columntable(retail)
glimpse(tbl) # Column overview
# Convert to long format
tbl_long = pivot_longer(tbl; id_cols = :date, names_to = :series, values_to = :value)
glimpse(tbl_long)
# Wrap in PanelData with group/date metadata, A simple struc for meta data, still a Table
panel_tbl = PanelData(tbl_long; groupby = :series, date = :date, m = 12)
glimpse(panel_tbl)
# Auto ARIMA with automatic xreg selection
spec = ArimaSpec(@formula(value = auto()))
# spec = ArimaSpec(@formula(value = p() + d() + q() + Q() + D() + Q() )) # Auto ARIMA
# spec = ArimaSpec(@formula(value = p(1)) # ARIMA(1,0,0)(0,0,0)[m]
fitted = fit(spec, panel_tbl)
# Inspect fitted models
glimpse(fitted)
# Forecast 12 steps ahead for every series
fc = forecast(fitted, h = 12)
# Inspect Forecast result
glimpse(fc)
# Forecast Table
fc_tbl = forecast_table(fc)
glimpse(fc_tbl)