Specify a multi-scale temporal random effect that decomposes temporal variation into trend, seasonal, and short-term components. Each component has its own variance parameter and structure.
This is particularly useful for long time series where patterns exist at multiple temporal scales (e.g., annual cycles, decadal trends).
Arguments
- time_var
Name of the time variable in data. Can be a formula (e.g.,
~ year) or a character string (e.g.,"year").- trend
Type of trend component:
"rw2"(default, smooth),"rw1"(less smooth), or"none".- seasonal
Period for seasonal component (integer). Set to
NULLor0for no seasonal component. Common values: 12 (monthly), 52 (weekly).- short_term
Type of short-term residual component:
"ar1"(default, correlated),"iid"(independent), or"none".- group_var
Optional name of grouping variable for panel data.
Logical; if TRUE (default), temporal effects enter both numerator and denominator.
- parameterization
Coordinate the intrinsic trend and seasonal arms are sampled in.
"centered"(default) samples the effects themselves."noncentered"samplesz ~ N(0, I)and reaches the effects throughsigma * A^-1 z, whereAstacks the arm's difference operator on1'/sqrt(n), so the variance enters the linear predictor through the transform rather than through a quadratic form. The two describe the same model; what differs is the geometry the sampler sees. Prefer"noncentered"when an arm's variance is shrunk toward zero, where a centred coordinate leaves a funnel it cannot descend: on a 500-observation fixture whose true trend is zero, the divergence count goes 30 of 2000 to 3, the bulk ESS ofsigma2_trend21 to 310 and its rhat 1.13 to 1.01, and the centred run reports a posterior median four times larger because it never reaches the small end. The short-term arm is proper and is the same block either way.- x
A ratiod_temporal_multiscale object
- ...
Ignored
Details
The multi-scale temporal model decomposes variation additively:
$$\eta(t) = trend(t) + seasonal(t) + short(t)$$
where:
trend(t): Long-term smooth change via RW1 or RW2
seasonal(t): Repeating pattern with period P via cyclic RW1
short(t): Residual temporal correlation via AR(1) or IID
Each component has a separate variance parameter with PC priors to favor simpler models (fewer active components).
Sum-to-zero constraints are applied to trend and seasonal components for identifiability with the intercept.
See also
temporal_rw1(), temporal_rw2(), temporal_ar1() for
single-component temporal effects, spatial_multiscale() for multi-scale
spatial effects
Examples
# Create multi-scale temporal specification
temporal_multiscale("month_id", trend = "rw2", seasonal = 12, short_term = "ar1")
#> tulpaRatio Multi-Scale temporal specification
#> =========================================
#>
#> Time variable: month_id
#>
#> Components:
#> Trend: RW2 (second-order random walk, smooth)
#> Seasonal: Period = 12 (cyclic RW1)
#> Short-term: AR(1) (autocorrelated residuals)
#>
#> Shared: Yes (enters both processes)
temporal_multiscale("year", trend = "rw2", seasonal = NULL, short_term = "none")
#> tulpaRatio Multi-Scale temporal specification
#> =========================================
#>
#> Time variable: year
#>
#> Components:
#> Trend: RW2 (second-order random walk, smooth)
#>
#> Shared: Yes (enters both processes)
# \donttest{
# Decompose into trend + seasonal + short-term
set.seed(129)
month_id <- 1:48
# Trend, 12-month cycle and AR(1) noise, shared by count and effort
eff <- 0.4 * sin(month_id / 15) + 0.4 * sin(2 * pi * month_id / 12) +
as.numeric(arima.sim(list(ar = 0.6), 48, sd = 0.15))
x <- rnorm(48)
df <- data.frame(
month_id = month_id,
x = x,
count = rpois(48, exp(3 + 0.3 * x + eff)),
effort = rgamma(48, shape = 4, rate = exp(-eff))
)
fit <- tratio(
count | effort ~ x,
data = df,
family = ratiod_poisson_gamma(),
temporal = temporal_multiscale(
time_var = "month_id",
trend = "rw2",
seasonal = 12,
short_term = "ar1"
),
control = list(iter = 1000, chains = 1, seed = 1)
)
#> Warning: 2 divergent transition(s) after warmup; raise `adapt_delta` or reparameterise.
# Extract and plot components
temporal_effects <- temporal(fit)
plot(temporal_effects, component = "trend")
# }