Skip to contents

This vignette covers three pieces of drmSEM that go beyond a plain directed DAG of distributional paths:

  1. Covariance edges — two responses that stay coupled after their predictors, declared with covary() and reported by covariances().
  2. Composite constructs — a weighted-sum or principal-component index of observed indicators, declared with drm_composite().
  3. Path attribution — splitting an indirect effect by mediator and by distributional channel with path_effects().

1. Covariance edges: covary() and covariances()

A directed path says “X causes a component of Y”. A covariance edge says something different: two responses are allowed to remain associated after their modelled predictors, with no direction and no mediated effect — the bidirected-edge convention of Bollen (1989) and Shipley (2016). drmSEM keeps the two ideas strictly separate (docs/design/07-bivariate-covariance-edges.md).

There are two kinds, and they answer different biological questions:

  • a residual correlation rho12 (within-observation, eps_y1 <-> eps_y2): “on a single occasion, when this individual’s activity is above its predicted mean, is its boldness also above its predicted mean?”;
  • a higher-level random-effect correlation corpair (between-unit, u_id,y1 <-> u_id,y2): “do individuals that average high on activity also average high on boldness?”.

covary() is the pure-R declaration primitive (it runs without the engine):

# residual (rho12) edge:
covary("activity", "boldness")
#> <covariance edge> rho12(activity, boldness) [residual]
# higher-level (corpair) edge sharing the `id` grouping:
covary("activity", "boldness", level = "id")
#> <covariance edge> corpair(id: activity, boldness) [higher-level]

Pass declarations to drm_sem() / drm_psem() via covariances =. They are reported by covariances() — kept out of paths(), which stays directed-only — and they make basis_set() / dsep() drop the activity _||_ boldness independence claim (Shipley’s bidirected-edge rule), because the model explicitly allowed the two to stay coupled.

sem <- drm_sem(
  activity = drm_node(drmTMB::bf(activity ~ temp), family = stats::gaussian()),
  boldness = drm_node(drmTMB::bf(boldness ~ temp), family = stats::gaussian()),
  data = dat,
  covariances = covary("activity", "boldness")
)
covariances(sem)   # the residual rho12 edge, separate from paths()
paths(sem)         # directed-only: temp -> activity, temp -> boldness
dsep(sem)          # the activity _||_ boldness claim is dropped

The grammar, accessors, d-separation consequence, and arc plotting ship today. What remains on the roadmap is the live bivariate engine step that reads non-NA rho12 / corpair estimates back from a joint drmTMB fit.

2. Composite constructs: drm_composite() and loadings()

A composite (formative) construct (Bollen and Lennox 1991; Grace and Bollen 2008) is a deterministic index built from two or more observed indicators before fitting — a weighted sum (method = "fixed") or the first principal-component score (method = "pca"). Once materialized it is an ordinary column, so a node formula can use it as a predictor or response, with no engine change. drm_composite() runs in pure R:

dat_ind <- data.frame(len = rnorm(50), mass = rnorm(50), wing = rnorm(50))
body_size <- drm_composite("body_size", c("len", "mass", "wing"),
                           method = "pca", data = dat_ind)
body_size
#> <composite construct> body_size = pca(len, mass, wing)
#> first-PC proportion of variance: 0.468
#> reliability (Cronbach's alpha): 0.284

Pass composites to drm_sem() via composites =; the construct column is built before fitting, and loadings() reports the indicator weights (kept separate from the structural paths()):

sem2 <- drm_sem(
  fitness = drm_node(drmTMB::bf(fitness ~ body_size + temp),
                     family = stats::gaussian()),
  data = dat,
  composites = drm_composite("body_size", c("len", "mass", "wing"), data = dat)
)
loadings(sem2)

This is the formative construct (indicators define the index). Reflective latent variables — a latent common cause with a measurement model — need a joint likelihood drmTMB does not fit piecewise, and are out of scope here (docs/design/09-latent-variables.md).

3. Path attribution: path_effects()

indirect_effects() routes through a set of mediators. path_effects() attributes that indirect effect to each mediator and to each mediator’s distributional channel.

By mediator (by = "mediator", the default), each gets an inclusion effect (only that mediator responds) and an exclusion effect (its marginal given the others), plus an explicit interaction_remainder — the pieces sum to the total only when the mediators act additively, and the remainder is reported rather than hidden:

path_effects(sem3, from = "temp", to = "survival")

By component (by = "component"), each mediator’s effect is split into a mean_channel plus one channel per non-mean component (sigma_channel, zi_channel, …) — the drop in the effect when that component is frozen at its reference value — and a component_remainder for the part that does not separate cleanly (under a nonlinear outcome the channels are not an exact partition, so the remainder is reported rather than hidden):

path_effects(sem3, from = "temp", to = "survival", by = "component")

This is a model-based decomposition, not a claim of nonparametric path-specific identification. path_effects(effect = "natural") also reports the natural per-mediator variant and includes an identified flag for the recanting-witness check. Live-fit integration and interval reporting remain roadmap items; see docs/design/02-effect-calculus.md.

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.
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.
Shipley, Bill. 2016. Cause and Correlation in Biology: A User’s Guide to Path Analysis, Structural Equations and Causal Inference with R. 2nd ed. Cambridge University Press.