Skip to content

drmSEM 0.2.0

Choose a tag to compare

@itchyshin itchyshin released this 06 Jun 19:32
39c7c36

drmSEM 0.2.0

Second release. Post-0.1 work: a unified effect-API surface, first-class
covariance-edge and composite-construct grammars, per-mediator and per-component
path attribution, finalized standardization conventions, and a scaffolded
Fisher's C calibration study. The any-component d-separation calibration remains
experimental until its (compute-heavy) study is run; everything else is
CI-validated against a live drmTMB or kernel-validated by closed-form tests.

Documentation

  • New vignette "Covariance edges, composites, and path attribution" walks
    through covary()/covariances(), drm_composite()/loadings(), and
    path_effects(). Every exported function now carries an example.

Path-specific effects (OQ-5, per-mediator)

  • path_effects(object, from, to, through=) decomposes the indirect effect into
    a per-mediator contribution: an inclusion effect (T({Mj}) - direct, only
    Mj responds) and an exclusion effect (T(all) - T(all \\ Mj), Mj's
    marginal given the rest), plus total_indirect and an explicit
    interaction_remainder. The pieces sum to the total only in the additive case;
    the remainder is reported, never forced to zero. Model-based attribution, not a
    nonparametric path-specific identification claim. The cross-world natural
    variant is the OQ-5 follow-up.
  • path_effects(by = "component") splits each mediator's effect into a
    mean_channel and one channel per non-mean component (sigma_channel,
    zi_channel, ... -- the drop when that component is frozen at its reference
    value), plus a component_remainder for the part that does not separate cleanly
    under a nonlinear outcome.

Composite latent constructs (0.3, first increment)

  • drm_composite(name, indicators, weights, method = c("fixed", "pca")) declares
    a composite (formative) construct — a weighted sum or first-PC index of
    observed indicator columns. It is materialized as an ordinary column before
    fitting, so a node formula can use it as a predictor or response with no engine
    change.
  • drm_sem() / drm_psem() gain a composites = argument; loadings(sem)
    reports the indicator-to-construct loadings, kept separate from paths().
  • Reflective (measurement-model) latent variables remain out of scope (they need
    a joint likelihood); see docs/design/09-latent-variables.md.

Inference hardening (towards 0.2)

  • Analytic effect cross-checks are now asserted tests (test-analytic-effects.R,
    pure-R, no engine): the Gaussian identity-link mean-mediated effect equals the
    coefficient product a*b*w; a non-mean (sigma) path contributes exactly
    nothing to the mean channel and the distribution-mediated effect goes to zero
    when the outcome is linear in the mediator; the distribution-mediated effect
    matches the lognormal closed form (and flips sign) across a downstream
    nonlinearity; natural and controlled effects diverge under an exposure-mediator
    interaction by the predicted amount; and the Poisson Pr(Y>0) and Gaussian
    Var(Y) outcome-functional effects match their closed forms.
  • Standardization conventions finalized and documented (OQ-4; see
    docs/design/08-standardization.md and ?standardize): standardized
    coefficients are reported on the link scale only; factor predictors keep SD = 1
    (raw per-contrast effect, lavaan std.nox convention); the latent divisor is
    per-component, so sigma/zi paths standardize on their own link scale. A
    Gelman 2-SD opt-in for continuous-vs-factor comparability and a theoretical-
    variance term for GLM mean paths are noted as tracked refinements.

Covariance edges: rho12 and corpair (OQ-14, grammar layer)

  • covary(y1, y2, level = ) declares a covariance edge between two responses
    — a residual correlation (rho12, within-observation, level = NULL) or a
    higher-level random-effect correlation (corpair, between-unit, a grouping
    level). Covariance edges are double-headed arcs: they carry no direction and
    no mediated effect.
  • drm_sem() / drm_psem() gain a covariances = argument that takes covary()
    declarations and validates them against the node records.
  • covariances(sem) reports residual and higher-level edges separately, kept
    out of paths() (which stays directed-only, including any x -> rho12 path).
  • basis_set() / dsep() are now covariance-aware: a declared rho12 /
    corpair edge between y1 and y2 drops the y1 _||_ y2 | predictors
    independence claim (Shipley's bidirected-edge rule).
  • This is the pure-R grammar/d-separation layer. drm_pair() (joint bivariate
    fitting), rho12() / corpairs() accessors that read a live fit, and
    double-headed-arc plotting need a bivariate drmTMB fit and remain on the
    roadmap (OQ-14).

Unified effect-API surface (OQ-12)

  • direct_effects(), total_effects(), and indirect_effects() now share one
    argument vocabulary: uncertainty = c("parametric", "none", "bootstrap"),
    nsim (inner distributional realizations), and population = c("conditional", "marginal"). total_effects() selects mediation with method = c("gcomp", "simulate").
  • The previous mediation, draw, and n_sim arguments are deprecated
    aliases
    — they still work but emit a deprecation warning, and the new
    argument wins when both are supplied. B (the number of uncertainty
    replicates) is unchanged. No simulation kernel changed.
  • Not-yet-implemented choices fail fast with a pointer to the tracking question:
    uncertainty = "bootstrap" (refit bootstrap, OQ-10) and population = "marginal" (marginalizing over the random-effect distribution, OQ-9).
  • direct_effects() gains target / threshold, so a controlled direct effect
    can be read on an outcome functional (p_gt, p_zero, var) as well as the
    mean, matching total_effects().