Skip to contents

drm_sem() is the declarative interface. You describe each endogenous node with drm_node(), or a joint two-response node with drm_pair(); drm_sem() fits each univariate node with drmTMB::drmTMB() and each pair as one bivariate model, then builds the same object drm_psem() returns. Causal paths are component-labelled: a predictor may target mu, sigma, nu, zi, hu, sd(group), or rho12 of a node.

Usage

drm_sem(
  ...,
  data,
  covariances = NULL,
  composites = NULL,
  latents = NULL,
  feedback = NULL,
  latent = NULL,
  na_action = c("warn", "common", "fail"),
  impute = c("none", "auto")
)

Arguments

...

Named drm_node() specifications and/or drm_pair() declarations. A pair may be unnamed: its two response variables become the node names.

data

A data frame supplied to every node fit.

covariances

Optional covary() declaration(s) (one object or a list) recording residual (rho12) or higher-level (corpair) covariance edges between responses; see covariances().

composites

Optional drm_composite() declaration(s). Each construct column is materialized from its indicators before fitting, so node formulas can reference it as an ordinary observed column; the loadings are reported by loadings().

latents

Optional drm_latent() declaration(s) or list of them. Each latent construct score is materialized from its indicators before fitting, so node formulas can reference it as an ordinary observed predictor or response; the measurement loadings are reported by loadings().

feedback

Optional drm_cycle() declaration(s) naming a feedback (cyclic) motif, allowing those nodes to form a cycle (every undeclared cycle stays an error). Node-wise ML of a declared cycle is inconsistent under simultaneity (a warning is emitted); equilibrium effects use the fixed-point propagator. See docs/design/10-cyclic-feedback.md.

latent

Character vector of marginalised latent vertex names (L_M). When supplied, basis_set() and dsep() generate and test m-separation claims on the implied MAG, conditioning on Richardson & Spirtes (2002) Corollary 5.3 anteriors (S = \\emptyset only). Pairwise claims are jointly licensed by Sadeghi & Lauritzen (2014) Theorem 3 / Lauritzen & Sadeghi (2018) Theorem 4 under a compositional-graphoid assumption (automatic for homoscedastic all-Gaussian nodes; otherwise faithfulness). Conditioned / selection latents are not supported. See docs/design/14-m-separation.md.

na_action

What to do when incomplete rows mean the nodes would not all be fitted on the same rows. "warn" (default) fits anyway but reports which nodes used how many rows; "common" fits every node on the shared complete-case set, so the piecewise SEM describes one sample; "fail" makes it an error. Each node's realized row count is recorded in attr(x, "alignment_issues") and in check_sem().

A piecewise SEM whose nodes are fitted on different samples is not the model the user asked for: path coefficients come from different row sets and the d-separation basis set is tested against yet another. The default warns rather than aborting so existing models keep fitting, but it never stays silent.

impute

Whether to derive missing-predictor imputation models from the graph. "none" (default) leaves missing data to the row-alignment policy above. "auto" derives, for each node with an incomplete endogenous parent, an imputation model equal to that parent's own node formula and family, and passes it to the engine as mi() + impute_model(). The user never writes an impute_model(): the causal graph specifies it, so the conditioning set is derived rather than guessed, and imputer and analysis model come from one graph.

Opt-in by design: imputation asserts a missing-at-random assumption, which is the user's call to make, not a silent default.

Because the SEM is piecewise, the downstream node re-estimates the parent's model inside its own likelihood rather than sharing the parent node's estimates. Imputation uncertainty is propagated within a node but not across nodes; this is a principled imputation, not full-information maximum likelihood across the SEM. Inspect what was derived with imputation().

Value

A drm_sem object.

References

Shipley B (2009). “Confirmatory Path Analysis in a Generalized Multilevel Context.” Ecology, 90(2), 363–368. doi:10.1890/08-1034.1 .

Lefcheck JS (2016). “piecewiseSEM: Piecewise Structural Equation Modelling in R for Ecology, Evolution, and Systematics.” Methods in Ecology and Evolution, 7(5), 573–579. doi:10.1111/2041-210X.12512 .

Brooks ME, Kristensen K, van Benthem KJ, Magnusson A, Berg CW, Nielsen A, Skaug HJ, Maechler M, Bolker BM (2017). “glmmTMB Balances Speed and Flexibility Among Packages for Zero-Inflated Generalized Linear Mixed Models.” The R Journal, 9(2), 378–400. doi:10.32614/RJ-2017-066 .

Rigby RA, Stasinopoulos DM (2005). “Generalized Additive Models for Location, Scale and Shape.” Journal of the Royal Statistical Society Series C: Applied Statistics, 54(3), 507–554. doi:10.1111/j.1467-9876.2005.00510.x .

Examples

if (FALSE) { # \dontrun{
sem <- drm_sem(
  size = drm_node(
    drmTMB::bf(size ~ temp + habitat + (1 | species), sigma ~ temp),
    family = stats::gaussian()
  ),
  abundance = drm_node(
    drmTMB::bf(abundance ~ size + temp + (1 | site), sigma ~ temp, zi ~ habitat),
    family = drmTMB::nbinom2()
  ),
  data = dat
)
paths(sem)
dsep(sem)
indirect_effects(sem, from = "temp", to = "abundance")
} # }