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.89379213  0.44528231  0.36182285 -0.17720657 0.28293309  0.08033562
#> trait_2  0.44528231  0.51382125  0.21102915 -0.06557509 0.22559646  0.11820257
#> trait_3  0.36182285  0.21102915  0.39962633 -0.23329927 0.01517766 -0.15572311
#> trait_4 -0.17720657 -0.06557509 -0.23329927  0.62308877 0.23669856  0.44183801
#> trait_5  0.28293309  0.22559646  0.01517766  0.23669856 0.56530303  0.46443061
#> trait_6  0.08033562  0.11820257 -0.15572311  0.44183801 0.46443061  0.69555420
#> 
#> $R
#>            trait_1    trait_2     trait_3    trait_4    trait_5    trait_6
#> trait_1  1.0000000  0.6570693  0.60541153 -0.2374579 0.39803827  0.1018883
#> trait_2  0.6570693  1.0000000  0.46570335 -0.1158932 0.41858686  0.1977222
#> trait_3  0.6054115  0.4657034  1.00000000 -0.4675320 0.03193281 -0.2953660
#> trait_4 -0.2374579 -0.1158932 -0.46753204  1.0000000 0.39882282  0.6711547
#> trait_5  0.3980383  0.4185869  0.03193281  0.3988228 1.00000000  0.7406528
#> trait_6  0.1018883  0.1977222 -0.29536602  0.6711547 0.74065283  1.0000000
#> 
#> $level
#> [1] "unit"
#> 
#> $part
#> [1] "total"
#> 
#> $note
#> character(0)
#> 
# }