
Reduced-rank spatial latent factors: spatial_latent(0 + trait | coords, d = K)
Source: R/brms-sugar.R
spatial_latent.RdCanonical name for the reduced-rank spatial random effect: K shared
SPDE fields drive all T traits via a T x K loading matrix
\(\boldsymbol\Lambda_{\mathrm{spa}}\). The spatial analogue of
phylo_latent() and the third cell of the spatial column of the API
grid (alongside spatial_indep() and spatial_dep()).
Arguments
- formula
0 + trait | coordsstyle formula (LHS is the trait factor0 + trait; RHS is thecoordsplaceholder symbol).- d
Integer; number of spatial latent factors (rank K). Defaults to 1.
- unique
Logical; include a per-trait unique spatial diagonal companion.
FALSEpreserves the old low-rank-onlyspatial_latent()path;TRUEfits the total spatial covariance \(\Lambda\Lambda^\top + \Psi\).- coords
Character; the column-name pair of spatial coordinates in
data(e.g.c("lon", "lat")). Resolved by the parser when supplied as keyword argument;NULLwhen the orientation expresses the coordinates via the formula RHS.- mesh
An
fmeshermesh object built viamake_mesh(). It may be supplied here or through the top-levelmesh =argument togllvmTMB(). The engine does not construct a mesh automatically fromcoords.- rho
Source-strength attenuation between 0 and 1, or
NULLto estimate it in a complete replicated multivariate Gaussian model without competing covariance. Omitted or explicit1preserves the existing model. Range remains a separate estimated parameter. Attenuation preserves the projected marginal variance at each modeled location and applies to the whole trait covariance, including Psi. The grouping column must identify locations consistently across replicates. Estimated latent models require rank one and at least four traits. The frozen spatial study found no passing recovery cell (14 partial and 2 blocked); rho intervals remain unvalidated. new-location prediction is not supported for attenuated models.
Details
Internally this rewrites to spde(form, .spatial_latent = TRUE, d = K)
and toggles the TMB template's spde_lv_k switch to K. With
unique = TRUE, the same SPDE tier also keeps the per-trait
omega_spde fields active, giving
\(\boldsymbol\Sigma_{\mathrm{spa}} =
\boldsymbol\Lambda_{\mathrm{spa}}\boldsymbol\Lambda_{\mathrm{spa}}^\top +
\boldsymbol\Psi_{\mathrm{spa}}\). The default unique = FALSE preserves
the older low-rank-only path. The earlier two-term companion spelling
is accepted as compatibility syntax for the same total-covariance
decomposition.
The C++ kernel
then reads a packed lower-triangular Lambda_spde and K shared spatial
fields omega_spde_lv (each prior \(\mathrm{N}(\mathbf{0},
\mathbf{Q}^{-1})\) where \(\mathbf{Q}\) is the SPDE precision built
from the mesh), and accumulates
\(\eta_o \mathrel{{+}{=}} \sum_k \Lambda_{\mathrm{spa},tk}\,
\omega_k(\mathbf{s}_o)\) per observation. Per-field \(\tau\) is
absorbed into \(\boldsymbol\Lambda_{\mathrm{spa}}\) for
identifiability, mirroring the phylo_latent() convention. Like all
rr loadings, \(\boldsymbol\Lambda_{\mathrm{spa}}\) is identified
only up to rotation; pin via lambda_constraint = list(spde = ...)
or post-hoc rotate via rotate_loadings().
Formula orientation
The canonical orientation is 0 + trait | coords (parallel to
latent() / indep() and glmmTMB's spatial keywords). The
earlier orientation coords | trait is accepted as a deprecated
alias and emits a one-shot lifecycle::deprecate_warn() per session
(introduced at gllvmTMB 0.1.4).
Examples
if (FALSE) { # \dontrun{
sim <- simulate_site_trait(
n_sites = 30, n_species = 6, mean_species_per_site = 5,
spatial_range = 0.4, sigma2_spa = rep(0.3, 6), seed = 1
)
mesh <- make_mesh(sim$data, c("lon", "lat"), cutoff = 0.1)
fit <- gllvmTMB(
value ~ 0 + trait +
spatial_latent(0 + trait | site, d = 2, mesh = mesh),
data = sim$data,
trait = "trait",
unit = "site"
)
} # }