Skip to contents

Canonical name for a reduced-rank latent-factor random effect at a grouping g. Formerly rr(0 + trait | g, d = K) – same engine, new name. The "rr" alias still works for backward compat but emits a one-shot deprecation warning per session.

Usage

latent(formula, d = 1, unique = TRUE, common = FALSE, lv = NULL)

Arguments

formula

0 + trait | g style formula (LHS is the response factor, typically 0 + trait; RHS is the grouping factor).

d

Integer; number of latent factors. The hard guard only requires d <= n_traits (the number of traits), but that is not the limit of what the data can identify. With the default unique = TRUE, each unit-trait cell observed once, and \(T\) traits, the covariance \(\boldsymbol\Sigma = \boldsymbol\Lambda\boldsymbol\Lambda^\top + \boldsymbol\Psi\) has \(T(T + 1)/2\) free entries to estimate \(T d - d(d - 1)/2 + T\) parameters (loadings up to rotation, plus the diagonal \(\boldsymbol\Psi\)). The counting rule of thumb is \((T - d)^2 \ge T + d\): \(T = 3\) and \(T = 4\) allow d <= 1, \(T = 5\) allows d <= 2, and \(T = 10\) allows d <= 6. Above it the split between \(\boldsymbol\Lambda\boldsymbol\Lambda^\top\) and \(\boldsymbol\Psi\) is not identified, and check_gllvmTMB() can flag only the symptoms (boundary \(\psi\), weak axes) after the fit. The rule is a necessary count, not a recovery guarantee. Replication within a unit, or unique = FALSE, changes the count.

unique

Logical; TRUE (default) auto-includes the diagonal trait-specific \(\boldsymbol\Psi\) companion (\(\boldsymbol\Sigma = \boldsymbol\Lambda\boldsymbol\Lambda^\top + \boldsymbol\Psi\)). Set FALSE for the loadings-only / rotation-invariant subset. The former argument name residual is retained as a soft-deprecated alias.

common

Logical; FALSE (default) estimates one diagonal \(\boldsymbol\Psi\) variance per trait. TRUE ties the default ordinary diagonal \(\boldsymbol\Psi\) companion to one shared variance across traits. Only applies when unique = TRUE.

lv

One-sided formula for predictor-informed latent-score means. The model matrix retains the formula's factor contrasts, then its intercept column is removed. With default treatment contrasts, lv = ~ group estimates differences from the factor reference level. Use stats::relevel() to select that level. Designs spanning a constant, including lv = ~ 0 + group, violate the no-LV-intercept contract and are rejected. Numeric lv = ~ x and lv = ~ 0 + x are equivalent. Runtime support is limited to ordinary unit-tier latent(..., lv = ~ x). Registered native family/link rows compose in one complete-response ordinary unit-tier block. The loadings-only unique = FALSE form admits ranks through the number of logical responses; automatic Psi additionally requires that its physical loading, latent-predictor, and engine-free diagonal parameters pass a necessary joint mean-covariance dimension screen. Passing that screen is not a recovery or interval-calibration certificate. Bounded rank-2/rank-3 canaries exercise every registered family, but broad composition recovery and interval calibration remain partial. Retained recovery and interval claims remain limited to their named cells. Source-specific *_latent(..., lv = ~ x) forms are parsed and then fail loud (not yet fittable). Where it is admitted, the fit is experimental and exploratory: extract the coefficients with extract_lv_effects(), whose default type = "axis_effect" output is rotation-dependent (an intrinsic latent-axis indeterminacy, not a defect – see extract_lv_effects() for the rotation-invariant type = "trait_effect" alternative). Repeated-sampling interval evidence is cell-specific; do not infer an interval claim for the mixed-response programme from its point-recovery evidence.

Value

A formula marker; never evaluated.

Details

Used inside a gllvmTMB() formula:

value ~ 0 + trait + latent(0 + trait | unit, d = 2)

By default, ordinary latent() now fits the canonical decomposition \(\boldsymbol\Sigma = \boldsymbol\Lambda \boldsymbol\Lambda^\top + \boldsymbol\Psi\), with the diagonal \(\boldsymbol\Psi\) companion included automatically:

value ~ 0 + trait + latent(0 + trait | unit, d = 2)

Set unique = FALSE for the loadings-only subset. For a scalar diagonal \(\boldsymbol\Psi\) companion shared across traits, use common = TRUE; this replaces the older two-term spelling for ordinary intercept-only latent terms.

See also

indep(), phylo_latent(), diag_re, extract_Sigma(), extract_lv_effects() for predictor-informed latent-score coefficients.

Examples

# Six traits on 60 units (3 replicate observations per unit): the
# between-unit trait covariance is rank two plus a trait-specific diagonal.
Lambda <- matrix(c(0.9, 0.7, 0.5, -0.4, 0.3, 0,
                   0, 0.2, -0.3, 0.6, 0.7, 0.8), ncol = 2)
sim <- simulate_unit_trait(
  n_units = 60, n_obs_per_unit = 3, n_traits = 6,
  Lambda_B = Lambda, psi_B = rep(0.2, 6), seed = 1
)
# A 2-factor latent random effect at `unit`. Ordinary latent() carries its
# diagonal Psi by default (Sigma = Lambda Lambda^T + diag(psi)).
# \donttest{
fit <- gllvmTMB(
  value ~ 0 + trait + latent(0 + trait | unit, d = 2),
  data = sim$data, trait = "trait", unit = "unit"
)
extract_Sigma(fit)
#> $Sigma
#>             trait_1     trait_2     trait_3     trait_4    trait_5     trait_6
#> trait_1  0.89381316  0.44527987  0.36182863 -0.17721641 0.28293618  0.08033305
#> trait_2  0.44527987  0.51381104  0.21102198 -0.06556966 0.22560004  0.11821218
#> trait_3  0.36182863  0.21102198  0.39961843 -0.23329437 0.01518318 -0.15571942
#> trait_4 -0.17721641 -0.06556966 -0.23329437  0.62308156 0.23669108  0.44183860
#> trait_5  0.28293618  0.22560004  0.01518318  0.23669108 0.56530768  0.46443667
#> trait_6  0.08033305  0.11821218 -0.15571942  0.44183860 0.46443667  0.69556687
#> 
#> $R
#>            trait_1    trait_2     trait_3    trait_4    trait_5    trait_6
#> trait_1  1.0000000  0.6570645  0.60542005 -0.2374697 0.39803629  0.1018829
#> trait_2  0.6570645  1.0000000  0.46569677 -0.1158854 0.41859594  0.1977384
#> trait_3  0.6054200  0.4656968  1.00000000 -0.4675295 0.03194461 -0.2953592
#> trait_4 -0.2374697 -0.1158854 -0.46752954  1.0000000 0.39881088  0.6711534
#> trait_5  0.3980363  0.4185959  0.03194461  0.3988109 1.00000000  0.7406527
#> trait_6  0.1018829  0.1977384 -0.29535925  0.6711534 0.74065271  1.0000000
#> 
#> $level
#> [1] "unit"
#> 
#> $part
#> [1] "total"
#> 
#> $note
#> character(0)
#> 
# }