This page is the syntax lookup for choosing a covariance keyword. The formula grammar has two decisions: what relates the grouping levels, and what covariance among traits is required at that grouping level.
Use Choose your next gllvmTMB step when you know the modelling task but need help locating this keyword reference or the next post-fit function.
The keywords below are live API, but a valid formula does not guarantee that a complex covariance is estimable from a particular data set. Fit health, replication, trait count, and the scientific covariance question still matter.
Choose in two steps
1. What relates the grouping levels?
- No prefix: levels are independent, as in an ordinary random effect.
-
animal_: individuals are related through a pedigree,A, orAinv. -
phylo_: species are related through a tree or phylogenetic covariance. -
spatial_: locations share a mesh-based spatial field, represented with a sparse Gaussian Markov random field (GMRF) approximation so nearby locations can be correlated. -
kernel_: levels are related through a supplied dense covariance matrixK— the generic dense-matrix source (the fifth grid row).
These sources are alternatives based on study design, not a progression from fine to broad scale. Add a source prefix only when that structured relationship is part of the estimand.
2. What trait covariance is needed?
There are three fundamental cross-trait structures, from simplest to richest:
-
indep: a separate marginal variance for each trait and zero cross-trait covariance — a diagonal model. Its parsimony modifiercommon = TRUEties all trait variances to one shared value (the scalar special case). -
dep: a full unstructured trait covariance with (T(T+1)/2) covariance parameters. Use only when trait count and grouping-level replication support a saturated covariance. -
latent: a parsimonious reduced-rank cross-trait covariance represented by (d) latent variables. Its modifierunique = TRUEadds the trait-diagonal companion.
scalar and unique are modifiers,
not separate modes. scalar is indep
with the variances tied to one shared value; unique is
latent with its
diagonal-
companion. This mirrors how the deprecated unique() keyword
now lives as latent(unique = TRUE). The named
scalar(), phylo_scalar(),
animal_scalar(), spatial_scalar(), and
kernel_scalar() keywords fit exactly this model but are
soft-deprecated compatibility syntax (they emit a
one-time warning); write indep(..., common = TRUE) in new
code.
All fitted keyword covariances are random-effect covariances on the model’s linear-predictor or latent scale. They are not automatically response-scale covariances for non-Gaussian traits.
The 5 × 3 grid
The rows are the five correlation sources across grouping levels; the columns are the three fundamental trait-covariance modes. Every cell is a live keyword. The scalar and unique sub-cases are modifiers, listed under the table.
| Source | Independent | Dependent | Latent |
|---|---|---|---|
| none |
indep()
|
dep()
|
latent()
|
| animal |
animal_indep()
|
animal_dep()
|
animal_latent()
|
| phylogenetic |
phylo_indep()
|
phylo_dep()
|
phylo_latent()
|
| spatial |
spatial_indep()
|
spatial_dep()
|
spatial_latent()
|
| kernel |
kernel_indep()
|
kernel_dep()
|
kernel_latent()
|
Scalar (one shared variance). Add
common = TRUE to any indep term —
e.g. indep(0 + trait | g, common = TRUE). The
soft-deprecated scalar() / *_scalar() keywords
fit the same model but warn once and are kept only for compatibility.
Omitting a multi-trait covariance term entirely means no such term is
fitted.
Unique
(diagonal-
companion). Add unique = TRUE to a
latent term (see the latent default below). The standalone
unique() keyword is soft-deprecated in favour of
indep() (for a plain diagonal) and
latent(unique = TRUE) (for the paired companion).
What the modes estimate
For the intercept-only grid, let be an entry of the relationship or model-implied covariance operator among grouping levels. For the ordinary no-prefix row, . Animal, phylogenetic, and dense-kernel inputs supply fixed covariance operators and may have non-unit diagonals. Spatial terms instead imply through a mesh-based precision whose range and scale parameters are estimated.
The clearest ordering-free definition is
where
is the trait covariance implied by the selected mode:
for indep (collapsing to the shared
under the common = TRUE / scalar modifier), a free
for dep, and
with an optional
companion for latent. This elementwise form does not depend
on whether software stacks traits or grouping levels first.
The diagonal in animal_indep() or
phylo_indep() is diagonal across traits,
but observations remain correlated within each trait
through the pedigree or phylogeny. It is not independent residual
noise.
The important latent default
Here, unique = is an argument of a latent term that
toggles its diagonal Psi companion; it is not a separate covariance mode
or a call to the deprecated covariance-function syntax.
The diagonal Psi companion is controlled differently across sources:
- ordinary
latent()includes by default; useunique = FALSEfor loadings only; -
animal_latent(),phylo_latent(),spatial_latent(), andkernel_latent()are loadings-only by default; - use
unique = TRUEon a source-specific or single-kernel latent term when that same source should also carry a trait-diagonal Psi component.
For animal, phylogenetic, and kernel models, source-specific Psi is diagonal across traits but still correlated across individuals, species, or other levels through the supplied relationship or covariance operator. Spatial Psi is also diagonal across traits, while each trait-specific field remains correlated across locations through the mesh-based spatial precision.
These diagonal statements describe intercept-only trait covariance.
With an augmented intercept-and-slope term,
*_indep(1 + x | group) estimates a per-trait
intercept–slope correlation (a double bar, 1 + x || group,
drops it). The random-slope section below gives the corresponding
blocks.
Ordinary long and wide syntax
The long and wide forms below express the same covariance choices. The Morphometrics article executes and compares both data shapes.
# Decomposed covariance: Lambda Lambda^T + Psi
fit_long <- gllvmTMB(
value ~ 0 + trait +
latent(0 + trait | individual, d = 2),
data = df_long,
trait = "trait",
unit = "individual"
)
fit_wide <- gllvmTMB(
traits(length, mass, wing, tarsus, bill) ~ 1 +
latent(1 | individual, d = 2),
data = df_wide,
unit = "individual"
)Replace latent(...) with indep(...) for a
diagonal baseline or dep(...) for a full covariance. In
wide formulas, 1 inside a bar-style term expands to the
long-form 0 + trait representation.
Exact source-specific syntax
The latent animal/phylogenetic helpers take the grouping column
directly. The indep and dep counterparts use a
bar formula, and the one-shared-variance (scalar) case is the
common = TRUE modifier on indep. Spatial
helpers all use the bar-form orientation.
Animal
animal_indep(0 + trait | id, pedigree = ped, common = TRUE) # one shared variance
animal_indep(0 + trait | id, pedigree = ped)
animal_dep(0 + trait | id, pedigree = ped)
animal_latent(id, d = 2, pedigree = ped) # loadings only
animal_latent(id, d = 2, pedigree = ped, unique = TRUE) # + animal PsiPhylogenetic
phylo_indep(0 + trait | species, tree = tree, common = TRUE) # one shared variance
phylo_indep(0 + trait | species, tree = tree)
phylo_dep(0 + trait | species, tree = tree)
phylo_latent(species, d = 2, tree = tree) # loadings only
phylo_latent(species, d = 2, tree = tree, unique = TRUE) # + phylo PsiUse tree = for the usual phylogenetic workflow.
vcv =, A =, and Ainv = support
advanced precomputed covariance/precision inputs; their row and column
names must match the grouping levels.
Spatial
spatial_indep(0 + trait | site, mesh = mesh, common = TRUE) # one shared variance
spatial_indep(0 + trait | site, mesh = mesh)
spatial_dep(0 + trait | site, mesh = mesh)
spatial_latent(0 + trait | site, d = 2, mesh = mesh)
spatial_latent(0 + trait | site, d = 2, mesh = mesh, unique = TRUE)Spatial models require a mesh built from the model’s coordinate
columns with make_mesh(). Pass that mesh either inside the
spatial keyword or through the top-level mesh = argument to
gllvmTMB(). A source-valid formula still needs enough
locations and spatial spread to identify range and covariance
parameters.
Dense kernels (the fifth grid row)
A supplied dense covariance matrix K is the generic
dense-matrix source. Its keywords follow the same grid as the other
sources, with the tied-variance case as the common = TRUE
modifier on kernel_indep().
kernel_indep(unit_id, K = K, name = "known", common = TRUE) # one shared variance x K
kernel_indep(unit_id, K = K, name = "known")
kernel_dep(unit_id, K = K, name = "known")
kernel_latent(unit_id, K = K, d = 2, name = "known")
kernel_latent(
unit_id, K = K, d = 2, name = "known", unique = TRUE
)For a single named kernel, unique = TRUE adds that
kernel’s diagonal Psi companion. Multiple named-kernel fits currently
use the latent-only route; do not assume that each component receives
its own Psi. When kernels overlap strongly, the fitted sum may be more
stable than attribution to individual kernel components.
Named kernels should encode a relationship fixed before fitting. The
model does not turn an analyst-supplied association matrix into evidence
of a causal or reciprocal process. When more than one named kernel is
fitted, use diagnose_kernel_separability() before
interpreting component-specific output; collapse indistinguishable
kernels rather than assigning them separate biological stories.
Other formula markers
Random slopes
phylo_slope(x | species) and
animal_slope(x | id) are live slope-only structured routes.
They are not additional covariance modes and should not be confused with
an augmented intercept-and-slope covariance such as
animal_dep(1 + x | id, ...) or
spatial_latent(1 + x | site, ...).
An augmented random-slope term describes deviations around a fixed population-average slope. Include that fixed slope separately:
# Long form
value ~ 0 + trait + (0 + trait):x +
phylo_indep(0 + trait + (0 + trait):x | species)
# Equivalent wide form
traits(t1, t2, t3) ~ 1 + x +
phylo_indep(1 + x | species)The three structured modes do not merely represent increasing
computational complexity. They estimate different covariance objects
(for a single slope x and
traits):
-
*_indep(1 + x | g)estimates independent per-trait (intercept, slope) blocks – each trait gets its own intercept variance, slope variance, and intercept–slope correlation, with no covariance across traits. Extract it atlevel = "phy"/"spatial"/"kernel". -
*_dep(1 + x | g)estimates a full interleaved covariance across all trait intercepts and slopes. Same extraction levels. -
*_latent(1 + x | g, d = K)estimates separate reduced-rank cross-trait covariance matrices for the intercept and slope columns; it does not estimate intercept–slope covariance. Extract the per-column matrices atlevel = "phy_slope"orlevel = "spde_slope".
Correlated and uncorrelated slopes: | and
||
There is one more choice for a random slope – whether the intercept and slope are correlated – and it is set by the number of bars, matching lme4/glmmTMB:
- A single bar,
mode(1 + x | g), estimates the intercept–slope correlation (the default). - A double bar,
mode(1 + x || g), drops it: the intercept and slope are uncorrelated. It is exactlymode(1 | g) + mode(0 + x | g).
The bar count sets only the intercept–slope coupling; the mode still sets the cross-trait structure. For traits:
| mode |
1 + x \| g (correlated) |
1 + x \|\| g (uncorrelated) |
|---|---|---|
indep |
a separate per trait | a per-trait intercept variance + slope variance (fully diagonal) |
dep |
full across all trait intercepts and slopes | a full intercept covariance and a full slope covariance, with intercepts slopes () |
latent |
separate reduced-rank per column block (already uncorrelated) | the same – \|\| is the explicit spelling |
Both bar forms are available for the phylo_,
animal_, kernel_, and spatial_
sources.
Choose the mode from the scientific covariance assumption, not as an
automatic fallback after a difficult fit. Centre and scale
x, retain the transformation, and confirm repeated,
overlapping within-unit coverage before fitting a random slope. The behavioural reaction-norm
guide shows those design checks for the ordinary Gaussian case.
Family-specific response requirements still apply; changing
family = is not the only change needed when moving from
continuous traits to counts, proportions, trials, or ordered
categories.
Known sampling covariance
meta_V() is not a grid row. It adds a known
observation/sampling covariance to a meta-analytic model rather than
estimating a random-effect trait covariance. The exact-additive route
requires the same row-aligned matrix in the formula marker and the
top-level argument:
value ~ 0 + trait + latent(0 + trait | study, d = 1) + meta_V(V = V)
# In gllvmTMB(...), also pass known_V = V.Use A/Ainv for relatedness and
V for known sampling covariance; they are different
scientific objects. This syntax lookup does not provide the applied
estimand, diagnostic, and interpretation workflow needed for a full
meta-analytic example. meta_known_V() remains a
soft-deprecated alias; new code uses meta_V().
What not to combine
At one grouping level and correlation source, specify one trait-covariance story:
- do not combine
depwithindeporlatentat that source; - do not combine standalone
indepwithlatentat that source; - the same rules apply to ordinary, animal, phylogenetic, spatial, and single-kernel terms.
Different grouping levels can carry different covariance terms—for
example, a between-individual latent() term and a
within-individual indep() term—when the design identifies
both.
If the first choice is too complex
-
Full
dep()is unstable or imprecise: try a lower-ranklatent()model, orindep()if cross-trait covariance is not essential. -
An added LV is weak or unstable across refits:
reduce
dand compare fit health and information criteria. - A diagonal variance is at zero: treat it as a boundary estimate; compare the simpler model rather than interpreting a tiny component literally.
- A relationship input fails: check grouping-level names, matrix dimensions, positive-semidefiniteness, tree tips, or mesh/data alignment.
- You are unsure which source prefix to use: return to the biological sampling design. A more elaborate source is not automatically a better model.
See Fit diagnostics before interpreting the selected covariance and Covariance and correlation for the corresponding estimands.
