Returns one row per trait and latent axis from a fitted gllvmTMB() model.
This is the report-ready companion to rotate_loadings() and to
plot(type = "ordination"): the same rotation, axis-ordering, sign-anchor,
and optional loading-standardization conventions are recorded in columns
instead of left inside a matrix.
Arguments
- fit
A fitted multivariate model returned by
gllvmTMB().- level
"unit"(between-unit) or"unit_obs"(within-unit). Deprecated aliases"B"and"W"are still accepted with a warning.- method
One of
"varimax","promax", or"none"; passed torotate_loadings().- order_axes
Logical. When
TRUE, reorder rotated axes by decreasing raw shared variance before tabulation. Ignored whenmethod = "none".- sign_anchor
One of
"auto"or"none"."auto"flips each rotated axis so its anchor trait has a positive loading. Ignored whenmethod = "none".- anchor_traits
Optional character vector of trait names used for sign anchoring. Supply one trait per axis after ordering. Axes without a supplied anchor use the trait with the largest absolute loading.
- loading_scale
One of
"raw"or"standardized"."raw"returns the rotated loadings on the fitted response scale."standardized"divides each trait loading by the square root of that trait's model-implied total variance, matchingplot(type = "ordination", standardize_loadings = TRUE).
Value
A data frame with columns level, trait, axis, loading,
abs_loading, axis_variance, axis_share, rotation, order_axes,
sign_anchor, anchor_trait, and loading_scale. axis_variance and
axis_share are computed from the rotated raw loading matrix before any
optional standardization; these are the quantities used to order axes.
Details
Scope: covered for fitted latent() components at level = "unit" or
level = "unit_obs" with raw or standardized point-estimate loadings.
This table does not attach uncertainty intervals to loadings. Bootstrap
or simulation-based uncertainty is not yet implemented and remains
possible future work for a later inference slice.
Examples
set.seed(1)
# Simulate six traits, each measured twice on 100 units (e.g. sites).
# Traits 2-3 share one latent axis, traits 4-6 share a second axis,
# and trait_1 loads on both.
Lambda <- cbind(c(0.7, 1.0, 0.9, 0.0, 0.0, 0.0),
c(0.7, 0.0, 0.0, 1.0, 0.9, 0.8))
sim <- simulate_unit_trait(n_units = 100, n_obs_per_unit = 2,
n_traits = 6, Lambda_B = Lambda,
psi_B = 0.4, sigma2_eps = 0.3)
fit <- gllvmTMB(value ~ 0 + trait +
latent(0 + trait | unit, d = 2, unique = TRUE),
data = sim$data, trait = "trait", unit = "unit")
# One row per trait and axis after varimax rotation. axis_share is the
# share of the shared (latent) variance carried by each axis.
tab <- extract_rotated_loadings_table(fit, level = "unit")
print(tab[, c("trait", "axis", "loading", "axis_share", "anchor_trait")],
digits = 2)
#> trait axis loading axis_share anchor_trait
#> 1 trait_1 LV1 0.530 0.52 trait_4
#> 2 trait_2 LV1 -0.040 0.52 trait_4
#> 3 trait_3 LV1 0.035 0.52 trait_4
#> 4 trait_4 LV1 0.968 0.52 trait_4
#> 5 trait_5 LV1 0.841 0.52 trait_4
#> 6 trait_6 LV1 0.872 0.52 trait_4
#> 7 trait_1 LV2 0.712 0.48 trait_3
#> 8 trait_2 LV2 0.941 0.48 trait_3
#> 9 trait_3 LV2 1.015 0.48 trait_3
#> 10 trait_4 LV2 -0.016 0.48 trait_3
#> 11 trait_5 LV2 0.061 0.48 trait_3
#> 12 trait_6 LV2 0.135 0.48 trait_3
# Standardized loadings divide by each trait's total between-unit
# standard deviation, so traits on different scales are comparable.
std <- extract_rotated_loadings_table(fit, level = "unit",
loading_scale = "standardized")
# The tidy layout makes filtering easy: the strong loadings per axis.
print(std[std$abs_loading > 0.5, c("axis", "trait", "loading")],
digits = 2)
#> axis trait loading
#> 4 LV1 trait_4 0.86
#> 5 LV1 trait_5 0.74
#> 6 LV1 trait_6 0.78
#> 7 LV2 trait_1 0.62
#> 8 LV2 trait_2 0.87
#> 9 LV2 trait_3 0.83
# Or reshape it back to a trait-by-axis grid.
round(xtabs(loading ~ trait + axis, data = std), 2)
#> axis
#> trait LV1 LV2
#> trait_1 0.46 0.62
#> trait_2 -0.04 0.87
#> trait_3 0.03 0.83
#> trait_4 0.86 -0.01
#> trait_5 0.74 0.05
#> trait_6 0.78 0.12
