Adds slope-only response-column deviations whose dependence is a Matérn
field evaluated at one labelled coordinate pair per response column. With
response-column by predictor coefficient matrix B, the model is
$$\mathrm{Cov}(\mathrm{vec}(B^\mathsf{T})) =
K_\mathrm{column}(\kappa) \otimes \Sigma,$$
where the projected SPDE covariance is normalized to unit diagonal at the
response-column coordinates. Thus Sigma alone carries marginal predictor
variance, while kappa controls practical range. Write a single | for a
full predictor covariance and || for a diagonal covariance. Both bars are
identical for one predictor. This term never adds a random intercept.
Arguments
- formula
A slope-only bar formula with bare numeric predictor names on the left and the resolved response-column factor on the right.
- mesh
A labelled
gllvmTMBmeshbuilt withmake_mesh()and a non-NULLid_colmatching the resolvedtrait =column name. Its retained row labels must match the response-column levels exactly.
Details
Build mesh from a trait-level coordinate table with
make_mesh(..., id_col = "trait"). Every response-column label must have
exactly one unique finite coordinate pair; labels are aligned by value, not
row order.
Scope
This route is covered for Gaussian long-format data and bare finite numeric predictors. Wide-format column slopes, non-Gaussian responses, transformed/factor bases, and latent predictor covariance are not supported in this release. Coordinate units are used as supplied; use an equal-distance projection and document the unit.
Examples
if (requireNamespace("fmesher", quietly = TRUE)) {
column_locations <- data.frame(
trait = paste0("sp", 1:6),
east_km = c(0, 1, 0, 1, 2, 2),
north_km = c(0, 0, 1, 1, 0, 1)
)
column_mesh <- make_mesh(
column_locations, c("east_km", "north_km"),
cutoff = 0.2, id_col = "trait"
)
df_long <- expand.grid(
unit = factor(paste0("site", 1:12)),
trait = factor(column_locations$trait, levels = column_locations$trait),
KEEP.OUT.ATTRS = FALSE
)
set.seed(130)
df_long$lat <- rnorm(nrow(df_long))
df_long$temp <- rnorm(nrow(df_long))
trait_id <- as.integer(df_long$trait)
df_long$value <- 0.1 * trait_id +
df_long$lat * seq(-0.3, 0.3, length.out = 6)[trait_id] +
df_long$temp * rep(c(-0.2, 0.2), 3)[trait_id] +
rnorm(nrow(df_long), sd = 0.25)
fit <- gllvmTMB(
value ~ 0 + trait + spatial_slope(lat + temp | trait,
mesh = column_mesh),
data = df_long, trait = "trait", unit = "unit",
family = gaussian(),
control = gllvmTMBcontrol(se = FALSE), silent = TRUE
)
extract_Sigma(fit, level = "column_slope")
}
#> $Sigma
#> lat temp
#> lat 0.06601909 0.01721757
#> temp 0.01721757 0.02161807
#>
#> $R
#> lat temp
#> lat 1.0000000 0.4557519
#> temp 0.4557519 1.0000000
#>
#> $level
#> [1] "column_slope"
#>
#> $part
#> [1] "dep"
#>
#> $source
#> $source$type
#> [1] "spatial"
#>
#> $source$grouping
#> [1] "trait"
#>
#> $source$labels
#> [1] "sp1" "sp2" "sp3" "sp4" "sp5" "sp6"
#>
#> $source$coordinates
#> east_km north_km
#> sp1 0 0
#> sp2 1 0
#> sp3 0 1
#> sp4 1 1
#> sp5 2 0
#> sp6 2 1
#>
#> $source$coordinate_columns
#> [1] "east_km" "north_km"
#>
#> $source$coordinate_units
#> [1] "as_supplied"
#>
#> $source$kappa
#> [1] 4.823628
#>
#> $source$practical_range
#> [1] 0.5863693
#>
#> $source$normalization
#> [1] "exact_projected_unit_diagonal"
#>
#> $source$K_column
#> [,1] [,2] [,3] [,4] [,5] [,6]
#> [1,] 1.0000000000 0.08033038 0.0925178728 0.01050194 0.0038777378 0.0007113854
#> [2,] 0.0803303756 1.00000000 0.0100080634 0.11317699 0.0674527005 0.0105019364
#> [3,] 0.0925178728 0.01000806 1.0000000000 0.06745270 0.0005933398 0.0038777378
#> [4,] 0.0105019364 0.11317699 0.0674527005 1.00000000 0.0100080634 0.0803303756
#> [5,] 0.0038777378 0.06745270 0.0005933398 0.01000806 1.0000000000 0.0925178728
#> [6,] 0.0007113854 0.01050194 0.0038777378 0.08033038 0.0925178728 1.0000000000
#>
#>
#> $predictors
#> [1] "lat" "temp"
#>
#> $column_labels
#> [1] "sp1" "sp2" "sp3" "sp4" "sp5" "sp6"
#>
#> $note
#> [1] "Slope-only response-column coefficients from the spatial source with a full predictor covariance. The response-column source covariance supplies the other Kronecker factor; this is not a trait-level Sigma."
#>
