Skip to contents

Functions to specify spatiotemporal interaction effects for ratio models. These capture dependencies that arise when spatial patterns vary over time, or when temporal trends differ across space.

Specify a spatiotemporal interaction effect for ratio models. The interaction captures structured or unstructured deviation from the additive spatial + temporal model.

Usage

spatiotemporal(
  spatial,
  temporal,
  type = c("I", "II", "III", "IV", "iid", "separable", "nonsep_gp"),
  shared = TRUE,
  parameterization = c("centered", "noncentered", "collapsed"),
  nonsep_type = c("product", "gneiting"),
  coords = NULL,
  cov_space = NULL,
  cov_time = NULL,
  nn = NULL
)

# S3 method for class 'ratiod_spatiotemporal'
print(x, ...)

Arguments

spatial

A spatial specification from spatial_car(), spatial_bym2(), or spatial_gp().

temporal

A temporal specification from temporal_rw1(), temporal_rw2(), temporal_ar1(), or temporal_gp().

type

Interaction type:

  • "I" or "iid": Unstructured interaction (IID)

  • "II": Structured time at each location

  • "III": Structured space at each time point

  • "IV": Fully structured (Kronecker product of spatial and temporal)

  • "separable": Separable space-time GP, the product covariance C_s(h) C_t(u) over the grid

  • "nonsep_gp": Non-separable space-time GP, see nonsep_type

shared

Logical; if TRUE (default), spatiotemporal effect enters both numerator and denominator. Set to FALSE for process-specific effects (triggers warning about potential confounding).

parameterization

With the HMC backend: "centered" (default) samples the interaction directly; "noncentered" samples a standard normal z and reconstructs the interaction from it, as z / sqrt(tau) for the Knorr-Held types ("I" to "IV") and through the nearest-neighbour GP autoregression, delta_i = m_i + sqrt(d_i) z_i, for the GP types. When the data carry little or no space-time interaction, the posterior for tau drifts toward large values and the centered field's conditional scale shrinks with it (a funnel), which NUTS cannot span with a single step size; "noncentered" decouples the two and should be tried first when rhat for the interaction (or an intercept sharing its geometry) will not drop with more warmup. "collapsed", for the GP types, integrates the interaction out with a Laplace approximation inside HMC (Margossian et al. 2020): the sampler moves the hyperparameters and every other block, and the interaction is drawn from its Gaussian approximation at each saved iteration. That removes the interaction's field-against-hyperparameter funnel; the marginal it targets is an approximation, exact for a Gaussian likelihood. It needs a log-concave family with canonical links (binomial, Poisson-gamma, negative binomial, gamma-gamma, lognormal) without zero inflation. An HSGP spatial margin is sampled centered. Ignored outside the HMC backend.

nonsep_type

For type = "nonsep_gp": "product" (the separable covariance) or "gneiting" (Gneiting 2002). An additive covariance is not among them: on a complete S x T grid its rank is S + T - 1, and the directions it drops are the space-time interactions the block carries.

coords

Required for "separable" and "nonsep_gp": a formula (~ lon + lat) or a character vector of two column names, giving the coordinates the interaction's covariance is built on. Where a spatial unit's rows carry different positions, the unit's coordinate is their centroid. The interaction's geometry is its own, so an areal spatial main effect pairs with a continuous interaction.

cov_space, cov_time

For the GP types: the spatial and temporal kernels, one of "exponential" (default), "matern", "gaussian", "spherical". phi is a lengthscale in all four.

nn

For the GP types: NNGP neighbours per grid cell (default 15, capped at S * T - 1), chosen on a joint space-time metric.

x

A ratiod_spatiotemporal object

...

Ignored

Value

A ratiod_spatiotemporal object

Details

Spatiotemporal interactions extend the basic additive model:

$$\eta_{st} = X\beta + f_s(space) + f_t(time)$$

to include interactions:

$$\eta_{st} = X\beta + f_s(space) + f_t(time) + \delta_{st}$$

where \(\delta_{st}\) captures space-time interactions.

Interaction Types (following Knorr-Held, 2000):

  • Type I: Unstructured interaction - IID \(\delta_{st} \sim N(0, \sigma^2)\)

  • Type II: Structured time, unstructured space - temporal structure at each location

  • Type III: Structured space, unstructured time - spatial structure at each time

  • Type IV: Structured space AND time - full Kronecker interaction

Separable Models:

  • Separable: Covariance is Kronecker product \(C_{st} = C_s \otimes C_t\)

  • Non-separable: GP with joint space-time metric

Type I (IID)

Independent random effect for each space-time combination: $$\delta_{st} \stackrel{iid}{\sim} N(0, \sigma^2_\delta)$$

This is the simplest form, requiring S*T parameters but capturing no structured interaction.

Type II (Temporal structure per location)

Each location has its own temporal random effect: $$\delta_{\cdot t}^{(s)} \sim RW(\sigma^2)$$

This captures location-specific temporal trends but assumes independence across locations.

Type III (Spatial structure per time point)

Each time point has its own spatial random effect: $$\delta_{s \cdot}^{(t)} \sim ICAR(\tau)$$

This captures time-specific spatial patterns but assumes independence across time points.

Type IV (Full structure)

Kronecker product of spatial and temporal precision matrices: $$Q_\delta = Q_s \otimes Q_t$$

This is the most constrained model, assuming the interaction has the same structure as the marginal effects.

Separable

For GP-based effects, assumes separable covariance: $$C(\mathbf{s}_1, t_1; \mathbf{s}_2, t_2) = C_s(\mathbf{s}_1, \mathbf{s}_2) \cdot C_t(t_1, t_2)$$

References

Knorr-Held, L. (2000). Bayesian modelling of inseparable space-time variation in disease risk. Statistics in Medicine, 19(17-18), 2555-2567.

Margossian, C. C., Vehtari, A., Simpson, D. and Agrawal, R. (2020). Hamiltonian Monte Carlo using an adjoint-differentiated Laplace approximation: Bayesian inference for latent Gaussian models and beyond. Advances in Neural Information Processing Systems 33.

Rue, H., Martino, S. and Chopin, N. (2009). Approximate Bayesian inference for latent Gaussian models by using integrated nested Laplace approximations. Journal of the Royal Statistical Society B, 71(2), 319-392.

Examples

# Create adjacency matrix for 10 regions
adj <- matrix(0, 10, 10)
for (i in 1:9) adj[i, i+1] <- adj[i+1, i] <- 1

# Type I: Unstructured interaction
st1 <- spatiotemporal(
  spatial = spatial_car(adj, level = "group", group_var = "region"),
  temporal = temporal_rw1("year"),
  type = "I"
)
print(st1)
#> tulpaRatio Spatiotemporal Interaction Specification
#> ===============================================
#> 
#> Interaction type: Type I: Unstructured (IID) 
#> 
#> Spatial component:
#>   Type: ratiod_spatial 
#>   Group variable: region 
#> 
#> Temporal component:
#>   Type: rw1 
#>   Time variable: year 
#> 
#> Shared: Yes (enters both processes) 

# Type IV: Fully structured interaction
st4 <- spatiotemporal(
  spatial = spatial_car(adj, level = "group", group_var = "region"),
  temporal = temporal_rw1("year"),
  type = "IV"
)
print(st4)
#> tulpaRatio Spatiotemporal Interaction Specification
#> ===============================================
#> 
#> Interaction type: Type IV: Fully structured (Kronecker) 
#> 
#> Spatial component:
#>   Type: ratiod_spatial 
#>   Group variable: region 
#> 
#> Temporal component:
#>   Type: rw1 
#>   Time variable: year 
#> 
#> Shared: Yes (enters both processes) 

# \donttest{
# Generate synthetic spatiotemporal data
set.seed(123)
n_regions <- 10
n_years <- 8
df <- expand.grid(
  region = 1:n_regions,
  year = 2015:(2015 + n_years - 1)
)
df$x <- rnorm(nrow(df))
df$count <- rpois(nrow(df), lambda = 20)
df$effort <- rgamma(nrow(df), shape = 4, rate = 1)

# Fit model with spatiotemporal interaction
fit <- tratio(
  count | effort ~ x,
  data = df,
  family = ratiod_poisson_gamma(),
  spatiotemporal = spatiotemporal(
    spatial = spatial_car(adj, level = "group", group_var = "region"),
    temporal = temporal_rw1("year"),
    type = "IV"
  ),
  control = list(iter = 400, chains = 1, seed = 1)
)
summary(fit)
#> ratio model summary
#> ===================
#> 
#> Inference: Exact (Tier 1) via hmc
#> Family: poisson_gamma 
#> 
#> Fixed effects (numerator):
#>        parameter  mean    sd   2.5% 97.5%  rhat ess_bulk
#>  num:(Intercept) 2.971 0.024  2.923 3.011 0.996      170
#>            num:x 0.022 0.069 -0.105 0.145 1.015       37
#> 
#> Fixed effects (denominator):
#>          parameter  mean    sd   2.5% 97.5%  rhat ess_bulk
#>  denom:(Intercept) 1.372 0.060  1.249 1.482 1.000      145
#>            denom:x 0.025 0.097 -0.188 0.190 1.035       49
#> 
#> Variance components:
#>     parameter    mean      sd   2.5%   97.5%  rhat ess_bulk
#>         shape   3.869   0.776  2.540   5.450 1.007       97
#>   tau_spatial 227.124 156.898 40.833 614.106 1.033       44
#>        tau_st   2.815   2.289  1.169   6.313 1.040       36
#>  tau_temporal 212.778 124.789 59.687 487.667 1.001       66
#> 
#> Other parameters:
#>    parameter   mean    sd   2.5% 97.5%  rhat ess_bulk
#>  temporal[1]  0.038 0.052 -0.075 0.130 0.997      161
#>  temporal[2]  0.031 0.041 -0.043 0.107 0.997      176
#>  temporal[3]  0.033 0.047 -0.073 0.131 0.997       88
#>  temporal[4] -0.019 0.042 -0.111 0.053 0.997       95
#>  temporal[5] -0.006 0.039 -0.080 0.074 0.995      145
#>  temporal[6] -0.035 0.044 -0.122 0.043 0.996      105
#>  temporal[7] -0.007 0.041 -0.088 0.064 1.014      150
#>  temporal[8] -0.034 0.049 -0.131 0.067 1.001      109
#> 
#> Diagnostics:
#>   Divergences: 0 
#>   Avg. acceptance: 0.293 
#>   Chains: 1 
#>   Iterations: 400 
#>   Warmup: 200 
#>   R-hat > 1.01 for 5 parameter(s), largest 1.040 (tau_st).
#>   Bulk ESS < 100 for 8 parameter(s), smallest 36 (tau_st).
#>   Run longer chains or reparameterise before using these estimates.
# }