Skip to contents

Canonical 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_scalar() and spatial_indep()).

Usage

spatial_latent(formula, d = 1, unique = FALSE, coords = NULL, mesh = NULL)

Arguments

formula

0 + trait | coords style formula (LHS is the trait factor 0 + trait; RHS is the coords placeholder symbol).

d

Integer; number of spatial latent factors (rank K). Defaults to 1.

unique

Logical; include a per-trait unique spatial diagonal companion. FALSE preserves the old low-rank-only spatial_latent() path; TRUE fits 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; NULL when the orientation expresses the coordinates via the formula RHS.

mesh

An fmesher mesh object built via make_mesh(). It may be supplied here or through the top-level mesh = argument to gllvmTMB(). The engine does not construct a mesh automatically from coords.

Value

A formula marker; never evaluated.

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"
  )
} # }