Skip to contents

Return per-entry CIs on either the raw reduced-rank loading matrix Lambda_<level> or the standardised loading rho[t,k] = Lambda[t,k] / sqrt(Sigma_total[t,t]) of a confirmatory gllvmTMB() fit. A numerical Jacobian of the complete requested loading vector is combined with the TMB sdreport() covariance. On the standardised scale this includes covariance among axes and uncertainty in fitted denominator components such as Psi.

Usage

loading_ci(
  fit,
  level = c("unit", "unit_obs"),
  method = c("wald", "wald_asym", "profile"),
  conf_level = 0.95,
  sigma_d2 = 1,
  loading_scale = NULL
)

Arguments

fit

A multivariate gllvmTMB() fit object.

level

Which loading matrix to summarise: "unit" (default) or "unit_obs". Legacy aliases "B" / "W" are accepted with a one-shot deprecation warning.

method

CI method:

"wald" (default)

Symmetric Wald via the joint delta method on the requested loading_scale.

"wald_asym"

Asymmetric Wald via the Fisher-z transformation on \(\rho_{tk} = \Lambda_{tk}/\sqrt{\Sigma_{total,tt}}\). This method is available only with loading_scale = "standardized"; its bounds stay in (-1, 1). It captures bounded-support asymmetry but not higher-order log-likelihood curvature.

"profile"

Profile-likelihood inversion through loading_profile(). This refits across a grid for each free loading entry and can be used when Wald inference is blocked by a non-positive-definite Hessian. The current profile target is raw Lambda, so loading_scale = "standardized" is refused.

conf_level

Confidence level. Defaults to 0.95.

sigma_d2

Deprecated compatibility argument; ignored. Standardised inference now derives each denominator from model-implied total variance via extract_Sigma() instead of accepting one scalar residual variance.

loading_scale

NULL, "raw", or "standardized". NULL uses "raw" for "wald" / "profile" and "standardized" for "wald_asym". Estimates, SEs, bounds, and downstream null regions are always on this recorded scale.

Value

A data frame (one row per Lambda entry) with columns trait, axis, estimate, se, lower, upper, method, loading_scale, and pinned. pinned = TRUE records that the raw loading was fixed by lambda_constraint. Its raw SE is zero, but its standardised SE can be nonzero because total variance can still vary.

Details

Per-entry CIs are only well-defined for confirmatory fits — i.e. fits supplied with a lambda_constraint that fixes enough entries to pin the rotation. Exploratory fits leave Lambda identified only up to a d x d orthogonal rotation, so the SE on any single Lambda[i, k] depends on the rotation convention and is not a biological quantity. This function therefore errors on exploratory fits and points the user at confirmatory_lambda() / suggest_lambda_constraint(), or at extract_communality() / extract_Sigma() for rotation-invariant summaries.

Interval calibration

Standardized symmetric joint-delta Wald intervals have an exact empirical certificate only for the structurally free strict-lower targets in native Laplace, pinned, unrotated, lower-triangular ordinary Gaussian unit-tier three-trait cells (n_units=150,d=2), (n_units=400,d=1), and (n_units=400,d=2), at conf_level = 0.95. The (n_units=150,d=1) cell did not meet the prespecified lower-coverage criterion. This is one simulation design: trait intercepts (-0.20, 0.10, 0.25), unique standard deviations (0.70, 0.80, 0.90), and loading vector (0.80, 0.45, -0.35) for d=1, with the second column (0, 0.70, 0.40) added for d=2. Coverage is conditional on eligible fits (optimizer convergence, converged fit health, an available sdreport(), and a positive-definite Hessian); availability was 98.82%, 93.38%, and 96.18% in the three certified cells, respectively. The certificate does not extend to another loading, unique-variance, or intercept regime. Pinned diagnostic rows, Fisher-z Wald (method = "wald_asym"), arbitrary confirmatory constraints, raw-loading intervals, profiles, bootstraps, other rotations, and every neighbouring family, tier, rank, sample size, or confidence level remain exploratory. The worked example below is binomial-probit and is outside the certified cells. See NEWS.md for the current coverage status.

See also

flag_unreliable_loadings() for a decision-aid summary; confirmatory_lambda() to build a confirmatory constraint matrix; extract_communality() for rotation-invariant alternatives.

Examples

if (FALSE) { # \dontrun{
# Build a confirmatory fit
M <- confirmatory_lambda(
  species  = species_names,
  group    = species_group,
  d        = 2L,
  loads_on = list(A = 1L, B = 2L)
)
fit <- gllvmTMB(
  value ~ 0 + trait + latent(0 + trait | site, d = 2L),
  data              = df_long,
  family            = binomial(link = "probit"),
  lambda_constraint = list(unit = M)
)
loading_ci(fit, level = "unit")
loading_ci(fit, level = "unit", loading_scale = "standardized")
} # }