Specify a conditional autoregressive (CAR) spatial random effect. Supports both intrinsic CAR (ICAR) and proper CAR variants.
Arguments
- adjacency
Adjacency matrix (sparse or dense). A symmetric matrix where entry (i,j) is 1 if areas i and j are neighbors, 0 otherwise.
- level
Level at which spatial structure applies:
"group": Spatial effect at the grouping variable level (e.g., sites). Requiresgroup_varto be specified."obs": Spatial effect at the observation level.
- group_var
Name of the grouping variable in data (required if
level = "group").- proper
Logical; if FALSE (default), uses Intrinsic CAR (ICAR) with rho = 1 fixed. If TRUE, uses proper CAR with rho estimated. See Details.
Logical; if TRUE (default), spatial effect enters both numerator and denominator linear predictors identically.
- parameterization
Parameterization of the spatial random effect. Either
"standard"(default) or"collapsed"to marginalize the spatial variance for improved mixing in sparse-graph regimes.- center
Logical; if TRUE (default), the field's mean is removed on its way into the linear predictor, so the intercept carries the level and the field carries deviations from it. The prior still reads the uncentred field.
center = FALSErequiresproper = TRUEand leaves the mean in the linear predictor, where it is jointly identified with the intercept: on a 36-unit fixture the two then correlate at -0.977 and the intercept's bulk ESS is 71 of 2000 against 1953 under the default, for the same posterior on the level. An intrinsic field (proper = FALSE) has no such choice, since its mean is unidentified until it is removed.
Details
The CAR model specifies that:
$$\phi_i | \phi_{-i} \sim N\left(\rho \frac{\sum_{j \sim i} \phi_j}{n_i}, \frac{\sigma^2}{n_i}\right)$$
where \(n_i\) is the number of neighbors of area i and \(j \sim i\) denotes that j is a neighbor of i.
This leads to a precision matrix: $$Q = \tau (D - \rho W)$$
where D is the diagonal matrix of neighbor counts and W is the adjacency matrix.
ICAR (proper = FALSE, default)
Sets rho = 1 (fixed)
Improper prior (rank-deficient Q)
Requires sum-to-zero constraint for identifiability
Simpler: one fewer parameter to estimate
Standard choice for disease mapping
Equivalent to RW1 on a graph
Proper CAR (proper = TRUE)
Estimates rho in (0, 1) from data
Proper prior (integrates to 1)
rho measures spatial autocorrelation strength
rho -> 0: approaches independence (IID)
rho -> 1: approaches ICAR
More flexible but additional parameter to estimate
Prior: rho ~ Beta(1, 1) (uniform on (0, 1))
See also
spatial_bym2() for decomposed spatial + IID effects,
spatial_gp() for continuous spatial effects
Examples
# Create adjacency matrix for 10 regions (chain structure)
adj <- matrix(0, 10, 10)
for (i in 1:9) {
adj[i, i+1] <- adj[i+1, i] <- 1
}
# ICAR (default, rho = 1 fixed)
icar <- spatial_car(adj, level = "group", group_var = "site")
print(icar)
#> tulpaRatio spatial specification
#> ===========================
#>
#> Type: ICAR (Intrinsic CAR)
#> Level: group
#> Spatial units: 10
#> Shared: Yes (enters both processes)
#> Group variable: site
#> (rho fixed at 1, sum-to-zero constraint applied)
# Proper CAR (rho estimated)
proper_car <- spatial_car(adj, level = "group", group_var = "site",
proper = TRUE)
print(proper_car)
#> tulpaRatio spatial specification
#> ===========================
#>
#> Type: Proper CAR
#> Level: group
#> Spatial units: 10
#> Shared: Yes (enters both processes)
#> Group variable: site
#> Rho bounds: [0, 1]
#> (spatial autocorrelation parameter, estimated from data)
# \donttest{
# Generate synthetic data with spatial structure
set.seed(123)
n_sites <- 10
n_per_site <- 5
df <- data.frame(
site = rep(1:n_sites, each = n_per_site),
x = rnorm(n_sites * n_per_site),
count = rpois(n_sites * n_per_site, 20),
effort = rgamma(n_sites * n_per_site, shape = 5, rate = 1)
)
# ICAR model (standard disease mapping approach)
fit_icar <- tratio(
count | effort ~ x,
data = df,
family = ratiod_poisson_gamma(),
spatial = spatial_car(adj, level = "group", group_var = "site"),
mode = "hmc",
control = list(iter = 400, chains = 1, seed = 1)
)
# Proper CAR model (estimate spatial autocorrelation)
fit_car <- tratio(
count | effort ~ x,
data = df,
family = ratiod_poisson_gamma(),
spatial = spatial_car(adj, level = "group", group_var = "site",
proper = TRUE),
mode = "hmc",
control = list(iter = 400, chains = 1, seed = 1)
)
# Extract rho from proper CAR
summary(fit_car) # Shows rho_spatial parameter
#> 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) 3.019 0.030 2.961 3.073 1.014 159
#> num:x -0.017 0.036 -0.085 0.046 1.004 180
#>
#> Fixed effects (denominator):
#> parameter mean sd 2.5% 97.5% rhat ess_bulk
#> denom:(Intercept) 1.605 0.070 1.491 1.764 0.998 170
#> denom:x 0.028 0.072 -0.105 0.183 1.006 108
#>
#> Variance components:
#> parameter mean sd 2.5% 97.5% rhat ess_bulk
#> rho_spatial 0.470 0.285 0.019 0.961 1.002 96
#> shape 4.759 0.845 3.213 6.448 1.017 70
#> tau_spatial 217.785 135.142 57.799 549.838 1.000 40
#>
#> Diagnostics:
#> Divergences: 0
#> Avg. acceptance: 0.899
#> Chains: 1
#> Iterations: 400
#> Warmup: 200
#> R-hat > 1.01 for 2 parameter(s), largest 1.017 (shape).
#> Bulk ESS < 100 for 3 parameter(s), smallest 40 (tau_spatial).
#> Run longer chains or reparameterise before using these estimates.
# }