Skip to contents

In observational and ecological research, many foundational concepts—such as individual quality, habitat degradation, boldness, or organismal size—cannot be measured directly with a single error-free variable. Instead, researchers measure a battery of correlated proxies (indicators) or combine multiple environmental drivers.

drmSEM supports latent, MIMIC, and composite measurement models within its piecewise structural equation modelling framework (Shipley 2000, 2009; Grace and Bollen 2008). This vignette explains:

  1. The distinction between formative, reflective, and MIMIC constructs.
  2. The declaration syntax: drm_latent(), drm_indicator(), and drm_composite().
  3. Identification constraints: marker indicator (λmarker=1\lambda_{\text{marker}} = 1) versus unit-variance (Var(η)=1\text{Var}(\eta) = 1).
  4. Reliability metrics: Cronbach’s α\alpha(Cronbach 1951) versus Raykov’s composite reliability ρ\rho(Raykov 1997; McDonald 1999).
  5. Distributional effect propagation: tracing causal interventions through latent constructs to downstream mean (μ\mu), dispersion (σ\sigma), and zero-inflation (zi\text{zi}) components.
  6. The honest piecewise paradigm: how factor scores are materialized and why indicator loadings are kept strictly separate from structural paths.

The three construct paradigms

Before writing formulas, it is critical to distinguish the causal direction between the latent variable η\eta and its observed variables (Bollen 1989; Bollen and Lennox 1991; Grace and Bollen 2005):

Construct type Causal topology Interpretation Declaration
Formative / Composite Indicators \to Construct Indicators define or cause the construct (e.g. Diet + Activity \to Body Condition). drm_composite() or drm_latent(type = "formative")
Reflective Latent \to Indicators Indicators are manifestations of a common underlying factor (e.g. Boldness \to Latency, Exploration, Aggression). drm_latent(type = "reflective")
MIMIC Causes \to Latent \to Indicators Multiple causes drive an unobserved state, which is reflected in multiple observable proxies (Jöreskog & Goldberger 1975). drm_latent(type = "mimic", causes = ...)

1. Formative constructs: drm_composite()

A formative construct is a deterministic or weighted combination of observed causes (Bollen and Lennox 1991; Grace and Bollen 2008). Because the indicators cause the construct, indicators are not required to correlate positively with each other, and internal-consistency reliability is not a validity requirement.

# Simulated morphometric data for 250 birds
n <- 250
dat <- data.frame(
  bill_length = rnorm(n, mean = 20, sd = 2),
  tarsus_length = rnorm(n, mean = 35, sd = 3),
  body_mass = rnorm(n, mean = 15, sd = 1.5),
  temp = rnorm(n, mean = 18, sd = 4)
)

# Build an equal-weighted composite index of body size
size_comp <- drm_composite(
  name = "structural_size",
  indicators = c("bill_length", "tarsus_length", "body_mass"),
  method = "fixed",
  data = dat,
  standardize = TRUE
)
size_comp
#> <composite construct> structural_size = fixed(bill_length, tarsus_length,
#> body_mass)
#> reliability (Cronbach's alpha): -0.01
#> score standardized (mean 0, sd 1)

When passed to drm_sem(), the composite score is materialized into the data frame prior to node fitting. Structural nodes can use structural_size as an ordinary predictor or response.


2. Reflective constructs: drm_latent(type = "reflective")

In a reflective construct, an unobserved latent variable η\eta drives multiple observable indicators:

yi=νi+λiη+εi,εi𝒩(0,θi)y_i = \nu_i + \lambda_i \eta + \varepsilon_i, \quad \varepsilon_i \sim \mathcal{N}(0, \theta_i)

where λi\lambda_i is the factor loading for indicator ii, and θi\theta_i is the unique (error) variance (Bollen 1989).

Identification constraints

Because η\eta is unobserved, its scale and origin are indeterminate without an identification constraint. drm_latent() provides two standard identification options:

  1. Marker variable identification (identification = "marker"): Fixes the loading of a reference indicator to λ1=1\lambda_1 = 1. The scale of η\eta is identical to the scale of that marker indicator.
  2. Unit-variance identification (identification = "unit_variance"): Constrains the latent variance to Var(η)=1\text{Var}(\eta) = 1. All indicator loadings λi\lambda_i are estimated freely as factor loadings.
# Generate data driven by a single latent trait: 'boldness'
boldness_true <- rnorm(n, mean = 0, sd = 1.5)
dat$exploratory_speed <- 1.0 * boldness_true + rnorm(n, sd = 0.5)
dat$novel_object_time <- 0.8 * boldness_true + rnorm(n, sd = 0.6)
dat$trap_latency      <- 0.6 * boldness_true + rnorm(n, sd = 0.7)

# Declare a reflective latent with marker identification:
refl_marker <- drm_latent(
  name = "boldness",
  indicators = c("exploratory_speed", "novel_object_time", "trap_latency"),
  type = "reflective",
  identification = "marker",
  marker = "exploratory_speed",
  data = dat
)
summary(refl_marker)
#> <latent construct: reflective> boldness (identification: marker)
#>          indicator loading std_loading
#>  exploratory_speed  1.0000      0.9520
#>  novel_object_time  0.8702      0.9235
#>       trap_latency  0.6970      0.8866
#> Composite reliability (Raykov's rho): 0.947
#> Reliability (Cronbach's alpha): 0.907

Notice that exploratory_speed has a loading of exactly 1.01.0, fixing the metric of the latent construct.

Alternatively, using identification = "unit_variance":

refl_uvar <- drm_latent(
  name = "boldness_std",
  indicators = list(
    drm_indicator("exploratory_speed"),
    drm_indicator("novel_object_time"),
    drm_indicator("trap_latency")
  ),
  type = "reflective",
  identification = "unit_variance",
  data = dat
)
summary(refl_uvar)
#> <latent construct: reflective> boldness_std (identification: unit_variance)
#>          indicator loading std_loading
#>  exploratory_speed  1.3969      0.9520
#>  novel_object_time  1.2156      0.9235
#>       trap_latency  0.9736      0.8866
#> Composite reliability (Raykov's rho): 0.947
#> Reliability (Cronbach's alpha): 0.907

3. MIMIC models: Multiple Indicators, Multiple Causes

A MIMIC (Multiple Indicators, Multiple Causes) construct (Jöreskog and Goldberger 1975) combines structural causes and reflective indicators in a single unified block:

η=jγjxj+ζ,ζ𝒩(0,ψ)\eta = \sum_{j} \gamma_j x_j + \zeta, \quad \zeta \sim \mathcal{N}(0, \psi)yi=λiη+εi,εi𝒩(0,θi)y_i = \lambda_i \eta + \varepsilon_i, \quad \varepsilon_i \sim \mathcal{N}(0, \theta_i)

Environmental causes x1,x2,x_1, x_2, \dots predict the latent variable η\eta, which in turn manifests in observed proxy indicators y1,y2,y_1, y_2, \dots.

# Environmental causes of condition
dat$food_availability <- rnorm(n)
dat$parasite_load     <- rnorm(n)
condition_true <- 0.7 * dat$food_availability - 0.5 * dat$parasite_load + rnorm(n, sd = 0.4)

# Reflective physiological indicators of condition
dat$hematocrit <- 1.0 * condition_true + rnorm(n, sd = 0.3)
dat$glucose    <- 0.75 * condition_true + rnorm(n, sd = 0.35)
dat$plasma_fat <- 0.55 * condition_true + rnorm(n, sd = 0.4)

# Downstream response: clutch size with location-scale effects
dat$clutch_size <- rnorm(
  n,
  mean = 4.0 + 0.8 * condition_true,
  sd = exp(0.1 - 0.4 * condition_true)
)

# Declare MIMIC construct:
mimic_cond <- drm_latent(
  name = "condition",
  causes = c("food_availability", "parasite_load"),
  indicators = list(
    drm_indicator("hematocrit", marker = TRUE),
    drm_indicator("glucose"),
    drm_indicator("plasma_fat")
  ),
  type = "mimic",
  identification = "marker",
  data = dat
)
summary(mimic_cond)
#> <latent construct: mimic> condition (identification: marker)
#> Structural causes: food_availability, parasite_load
#>   indicator loading std_loading
#>  hematocrit  1.0000      0.9453
#>     glucose  0.7728      0.9247
#>  plasma_fat  0.6464      0.8915
#> Composite reliability (Raykov's rho): 0.947
#> Reliability (Cronbach's alpha): 0.9

4. Construct reliability: α\alpha versus Raykov’s ρ\rho

Assessing construct quality is essential before interpreting structural pathways. drmSEM provides both classical Cronbach’s α\alpha and modern composite reliability:

Cronbach’s α\alpha

α=kk1(1i=1kσi2i=1kj=1kσij)\alpha = \frac{k}{k - 1} \left(1 - \frac{\sum_{i=1}^k \sigma_i^2}{\sum_{i=1}^k \sum_{j=1}^k \sigma_{ij}}\right)

Cronbach’s α\alpha(Cronbach 1951) assumes essential τ\tau-equivalence (all indicators share identical factor loadings λ1=λ2==λk\lambda_1 = \lambda_2 = \dots = \lambda_k). When loadings differ (as is almost universally true in real biological data), α\alphaunderestimates scale reliability (Raykov 1997).

Raykov’s composite reliability ρ\rho (McDonald’s ω\omega)

ρ=(i=1kλi)2Var(η)(i=1kλi)2Var(η)+i=1kθi\rho = \frac{\left(\sum_{i=1}^k \lambda_i\right)^2 \text{Var}(\eta)}{\left(\sum_{i=1}^k \lambda_i\right)^2 \text{Var}(\eta) + \sum_{i=1}^k \theta_i}

Raykov’s ρ\rho(Raykov 1997; McDonald 1999) allows congeneric indicators with unequal loadings λi\lambda_i and unique error variances θi\theta_i.

# Compute standalone metrics on an indicator matrix
ind_df <- dat[c("hematocrit", "glucose", "plasma_fat")]

alpha_val <- drm_cronbach_alpha(ind_df)
rho_val   <- drm_raykov_rho(ind_df)

c("Cronbach's alpha" = alpha_val, "Raykov's rho" = rho_val)
#> Cronbach's alpha     Raykov's rho 
#>        0.9002408        0.9493847

When indicator loadings vary substantially, Raykov’s ρ\rho gives the honest, unattenuated measure of composite reliability.


5. Assembling the SEM and estimating distributional pathways

In drmSEM, latent and composite constructs integrate seamlessly into piecewise structural equation models via the latents = or composites = arguments:

sem <- drm_sem(
  # Node 1: Condition driven by environmental causes
  condition = drm_node(
    drmTMB::bf(condition ~ food_availability + parasite_load),
    family = stats::gaussian()
  ),
  # Node 2: Clutch size has location (mu) AND scale (sigma) predicted by condition
  clutch_size = drm_node(
    drmTMB::bf(
      clutch_size ~ condition,
      sigma ~ condition
    ),
    family = stats::gaussian()
  ),
  data = dat,
  latents = mimic_cond
)
#>  Fitting node "condition"
#>  Fitting node "clutch_size" [98ms]
#> 
#>  Fitting node "clutch_size"
#>  Fitting node "clutch_size" [73ms]
#> 

summary(sem)
#> 
#> ── drmSEM summary ──────────────────────────────────────────────────────────────
#> 2 endogenous nodes; order "condition" and "clutch_size"
#> 
#> ── Edges by component ──
#> 
#> mu: 3
#> sigma: 1
#> 
#> ── Paths ──
#> 
#> <drmSEM paths: 4 component-labelled coefficients>
#>               from          to component     link              term estimate
#>  food_availability   condition        mu identity food_availability   0.6819
#>      parasite_load   condition        mu identity     parasite_load  -0.4726
#>          condition clutch_size        mu identity         condition   0.8078
#>          condition clutch_size     sigma      log         condition  -0.4797
#>  std.error statistic   p.value endogenous
#>     0.0303    22.495 4.65e-112      FALSE
#>     0.0319   -14.802  1.43e-49      FALSE
#>     0.0622    12.981  1.58e-38       TRUE
#>     0.0507    -9.458  3.14e-21       TRUE

Inspecting structural paths vs indicator loadings

drmSEM strictly separates structural paths between nodes from indicator measurement loadings:

# Structural regression coefficients between nodes
paths(sem)
#> <drmSEM paths: 4 component-labelled coefficients>
#>               from          to component     link              term estimate
#>  food_availability   condition        mu identity food_availability   0.6819
#>      parasite_load   condition        mu identity     parasite_load  -0.4726
#>          condition clutch_size        mu identity         condition   0.8078
#>          condition clutch_size     sigma      log         condition  -0.4797
#>  std.error statistic   p.value endogenous
#>     0.0303    22.495 4.65e-112      FALSE
#>     0.0319   -14.802  1.43e-49      FALSE
#>     0.0622    12.981  1.58e-38       TRUE
#>     0.0507    -9.458  3.14e-21       TRUE

# Indicator loadings (measurement model)
loadings(sem)
#> <drmSEM composite/latent loadings: 1 construct>
#>  composite  indicator loading std_loading method  type identification
#>  condition hematocrit  1.0000      0.9453    pca mimic         marker
#>  condition    glucose  0.7728      0.9247    pca mimic         marker
#>  condition plasma_fat  0.6464      0.8915    pca mimic         marker

# Construct reliability summary across all latent blocks
reliability(sem)
#> <drmSEM construct reliability: 1 construct>
#>  composite  type method n_indicators  alpha    rho    ave prop_var
#>  condition mimic    pca            3 0.9002 0.9469 0.8478   0.8478

6. Distributional effect propagation through latent nodes

A central strength of drmSEM is that causal effects are component-labelled. A path from a latent construct to a downstream node can target the mean (μ\mu), the dispersion / scale (σ\sigma), the shape (ν\nu), or the zero-inflation (zi\text{zi}) component.

Suppose we intervene on food_availability, shifting it by +1.0+1.0 standard deviation. What happens downstream to clutch_size?

# Simulate total interventional effects of food_availability on clutch_size
eff <- total_effects(sem, from = "food_availability", to = "clutch_size", nsim = 200)
eff
#> <drmSEM effect>
#>               from          to    scale mediation target estimate conf.low
#>  food_availability clutch_size response      mean   mean   0.5241   0.4337
#>  conf.high
#>     0.6164

Interpreting component-labelled pathways

  • Path condition -> clutch_size (mu): Increases the expected mean clutch size.
  • Path condition -> clutch_size (sigma): Modulates the residual variation or reproductive risk among individuals. This is not a mean effect. A negative σ\sigma path indicates that birds in higher condition have more predictable, less erratic clutch sizes.

By simulating forward through the structural graph, drmSEM correctly propagates interventions through the latent construct to all modelled distributional parameters simultaneously.


Summary of best practices

  1. Choose the right construct model: Use drm_composite() when indicators are causes/inputs (formative); use drm_latent() when indicators are reflections/proxies of an underlying factor.
  2. Select an identification rule: Use marker when you want the latent construct to inherit the scale of a primary reference trait; use unit_variance when you want a standardized factor score.
  3. Check composite reliability: Report Raykov’s ρ\rho alongside Cronbach’s α\alpha to ensure proxy indicators measure a congeneric construct reliably (ρ0.70\rho \ge 0.70).
  4. Distinguish structural paths from loadings: In publications, report measurement loadings (λi\lambda_i) separately from structural regressions (βj\beta_{j}).
  5. Embrace distributional targets: Use location-scale formulas (sigma ~ eta) when latent quality stabilizes or destabilizes downstream biological traits.

References

Bollen, Kenneth A. 1989. Structural Equations with Latent Variables. Wiley.
Bollen, Kenneth A., and Richard Lennox. 1991. “Conventional Wisdom on Measurement: A Structural Equation Perspective.” Psychological Bulletin 110 (2): 305–14. https://doi.org/10.1037/0033-2909.110.2.305.
Cronbach, Lee J. 1951. “Coefficient Alpha and the Internal Structure of Tests.” Psychometrika 16 (3): 297–334. https://doi.org/10.1007/BF02310555.
Grace, James B., and Kenneth A. Bollen. 2005. “Interpreting the Results from Multiple Regression and Structural Equation Models.” Bulletin of the Ecological Society of America 86 (4): 283–95. https://doi.org/10.1890/0012-9623(2005)86[283:ITRFMR]2.0.CO;2.
Grace, James B., and Kenneth A. Bollen. 2008. “Representing General Theoretical Concepts in Structural Equation Models: The Role of Composite Variables.” Environmental and Ecological Statistics 15 (2): 191–213. https://doi.org/10.1007/s10651-007-0047-7.
Jöreskog, Karl G., and Arthur S. Goldberger. 1975. “Estimation of a Model with Multiple Causes and Multiple Indicators of a Single Latent Variable.” Journal of the American Statistical Association 70 (351): 631–39. https://doi.org/10.1080/01621459.1975.10482485.
McDonald, Roderick P. 1999. Test Theory: A Unified Treatment. Lawrence Erlbaum Associates.
Raykov, Tenko. 1997. “Estimation of Composite Reliability for Congeneric Measures.” Applied Psychological Measurement 21 (2): 173–84. https://doi.org/10.1177/01466216970212006.
Shipley, Bill. 2000. “A New Inferential Test for Path Models Based on Directed Acyclic Graphs.” Structural Equation Modeling 7 (2): 206–18. https://doi.org/10.1207/S15328007SEM0702_4.
Shipley, Bill. 2009. “Confirmatory Path Analysis in a Generalized Multilevel Context.” Ecology 90 (2): 363–68. https://doi.org/10.1890/08-1034.1.