Estimate frequency/trend windows from ACF with spectral fallback
decomp_freq_trend.RdComputes data-driven window lengths (in **seconds**) for seasonal
(`frequency`) and trend (`trend`) components used by
anomalize::time_decompose (works for both method = "stl" and
method = "twitter"). The primary estimator selects the earliest
statistically significant **local maximum** in the autocorrelation function
(ACF). If no such peak exists, a fallback uses the dominant peak of the
periodogram (excluding near-DC). The resulting base period is then scaled and
clamped to avoid pathological window sizes.
Usage
decomp_freq_trend(
ts,
fac.f = 1,
fac.t = 1.5,
max_period_frac = 0.2,
lag.max = NULL,
use_fft_fallback = TRUE
)Arguments
- ts
A numeric or
tstime series. Ifts, itsfrequency(ts)is used upstream when computing the ACF; here we only consume the ACF output assuming lags are already in seconds.- fac.f
Numeric scalar. Multiplier for the seasonal window (default
1.0). For the Twitter method,1.0aligns with the base period; increase to widen the seasonal window.- fac.t
Numeric scalar. Multiplier for the trend window (default
1.5). Typical Twitter heuristic is~1.5–2.0.- max_period_frac
Numeric in
(0,1). Upper bound on the candidate period as a fraction of the series duration (default0.2). Prevents overly long periods relative to batch length.- lag.max
Integer. Maximum lag forwarded to
ACF()(default:min(4096, length(ts)-1)).- use_fft_fallback
Logical. If
TRUE(default), usestats::spec.pgramfallback when no significant ACF peak is found.
Value
A list with two numeric scalars (in **seconds**):
freq— seasonal window length forfrequency=trend— trend window length fortrend=
These strings are typically passed as paste(value, "seconds") to
anomalize::time_decompose().
Details
- Assumes the input ACF() returns lag in **seconds** (as in
your current implementation). The effective sampling interval \(\Delta t\)
is inferred as median(diff(lag)).
- **Primary rule**: pick the first lag \(\tau > 0\) such that
\(\mathrm{ACF}(\tau)\) is a local maximum and exceeds the white-noise
95% CI.
- **Fallback**: choose \(\tau = (1/f_\mathrm{dom}) \Delta t\) from the
dominant periodogram frequency (excluding a small region near DC).
- Windows are constructed as
$$\mathrm{frequency} = \max(2\Delta t, \min(f_\mathrm{fac}\,\tau, \tau_\max))$$
$$\mathrm{trend} = \max(1.1\,\mathrm{frequency}, \min(t_\mathrm{fac}\,\tau, \tau_\max))$$
where \(\tau_\max = \min(\max(\mathrm{lag}),\, \mathrm{max\_period\_frac}\cdot N\Delta t)\).
See also
acf, spec.pgram,
time_decompose