API overview
Public exports are listed on the module docstring. Prefer MediationSpec + run_mediation for new code. Certificate bridges sit beside estimation; see Getting started.
Module
CausalMediation.CausalMediation — Module
CausalMediationCross-fitted mediation estimation for the CDCS stack: interventional (RI), natural, organic, controlled direct, and recanting-twin path-specific effects.
Depends on CausalDynamics for identification certificates and CausalTargeted for Super Learner, ShiftPolicy / DiscreteTreatmentPolicy, fold helpers, and density ratios.
Entry points
MediationSpec/run_mediation— typed estimaterun_mediation_grid— δ-gridDataFrameAPIplan_mediation/spec_from_identification— ID bridgedecompose— TE / NDE / NIE (or path) extraction
Documentation
- Documenter site: https://simonab.github.io/CausalMediation.jl/dev/
- Design:
DESIGN.md· Boundaries:BOUNDARIES.md· Naming:NAMING.md
Effect types and specification
CausalMediation.MediationEffect — Type
MediationEffectSupertype for mediation estimand families (interventional, natural, organic, recanting-twin, controlled direct).
CausalMediation.InterventionalMediation — Type
Interventional (randomised intermediate) mediation — RI / Vansteelandt–Daniel.
CausalMediation.NaturalMediation — Type
Natural direct/indirect effects (Pearl / Robins–Greenland); requires empty moc.
CausalMediation.OrganicMediation — Type
Organic direct/indirect effects (Lok 2015).
CausalMediation.RecantingTwinMediation — Type
Recanting-twin / path-specific effects (Vo–Díaz).
CausalMediation.ControlledDirect — Type
Controlled direct effect with continuous mediators fixed at m.
Estimation supports cross-fitted outcome-regression estimator=:plugin only; it does not return inferential standard errors or confidence limits. Empty moc is required. An omitted estimator selects :plugin for this effect.
CausalMediation.MediationSpec — Type
MediationSpec(treatment, outcome; mediators, covariates, moc, policy_d0, policy_d1, effect)Typed mediation estimand: treatment, outcome, mediators, baseline covariates, intermediate confounders (moc), shift policies, and effect family.
Arguments
mediators: mediator column symbols (required)covariates: baseline adjustment set (often fromIdentificationResult.adjustment)moc: mediator–outcome confounders (intermediate confounders ofMandYthat are affected by treatment). First-class onMediationSpecand on CausalDynamicsIdentificationResult.moc. Must be empty forNaturalMediation; nonemptymocselects interventional / organic / RT families that condition on these post-treatment variables.policy_d0/policy_d1: CausalTargetedShiftPolicy(numeric MTP) orDiscreteTreatmentPolicy(factor recode). Both arms must be the same kind. Discrete policies are interventional only, with continuous mediators and emptymocin this version.effect:InterventionalMediation()by default
See also plan_mediation, run_mediation, assumptions.
CausalMediation.MediationResult — Type
MediationResultPoint estimates, SEs, influence curves, and diagnostics for a mediation run.
Fields include estimates / se (typically :te, :nde, :nie), a full δ-grid table (DataFrame), and diagnostics (n_mc, estimator, …). Use decompose for a compact TE/NDE/NIE (or path) NamedTuple.
CausalMediation.assumptions — Function
assumptions(spec) -> NamedTupleNamed assumption checklist shared by identify gates and run_mediation.
CausalMediation.assert_natural_admissible! — Function
assert_natural_admissible!(spec)Refuse natural effects when intermediate confounders (moc) are present.
CausalMediation.assert_causal_mediator_paths! — Function
assert_causal_mediator_paths!(spec; relation_kinds=nothing, require=false)Refuse mediation along constitutive, participation, measurement, or other non-influence relations. Ordinary mediation requires a declared :causal_influence kind on every edge of every treatment → mediator → outcome route (MediationRelationKinds lists accepted forms).
Relation kind is declared, never inferred: with a per-edge dictionary or a TemporalDAGSpec, each route edge must be present — a missing declaration is an error, not a silently assumed causal edge. Mediator-to-mediator edges are optional but, when declared, must also be causal. With the coarse per-mediator dictionary every mediator must be declared.
When relation_kinds === nothing nothing is checked and nothing is returned, unless require = true, in which case the absence is itself refused (used by plan_mediation when the certificate comes from a semantically typed graph).
CausalMediation.MediationRelationKinds — Type
Declared relation kinds accepted by assert_causal_mediator_paths!:
AbstractDict{Tuple{Symbol,Symbol},Symbol}— one declared kind per directed edge(source, target); the preferred form.AbstractDict{Symbol,Symbol}— one declared kind per mediator, read as the kind of every path edge touching that mediator (coarse legacy form).CausalDynamics.TemporalDAGSpec/TemporalUnrolling— kinds are read from the declaredLaggedEdge.relation_kindvalues.
CausalMediation.assert_moc_for_ri! — Function
assert_moc_for_ri!(spec)Document that interventional effects admit moc (no-op gate for API symmetry).
CausalMediation.decompose — Function
decompose(result) -> NamedTupleExtract TE / NDE / NIE (or path-specific components) from a MediationResult.
Identification bridge
CausalMediation.plan_mediation — Function
plan_mediation(spec, id_result; shift) -> MediationSpecCertificate-first planning: merge adjustment / mediators / moc from a CausalDynamics IdentificationResult into a concrete MediationSpec (mirrors CausalTargeted plan_mtp).
Empty fields on spec are filled from the certificate; nonempty fields are kept. Optional shift replaces both policy_d0 and policy_d1 (numeric or discrete).
relation_kinds (see MediationRelationKinds) declares the relation kind of every mediation route edge; pass the TemporalDAGSpec the certificate was derived from when available. When id_result.semantic_fingerprint is set the certificate came from a semantically typed graph and relation_kinds is required — the planner refuses to assume that imported paths are causal.
CausalMediation.spec_from_identification — Function
spec_from_identification(id_result; effect, policy_d0, policy_d1) -> MediationSpecBuild a MediationSpec from an IdentificationResult whose query is a CausalDynamics MediationQuery.
Uses id_result.adjustment, .mediators, and .moc. When effect is the default :interventional and the query carries a different effect_kind, that kind is preferred.
Estimation
CausalMediation.run_mediation — Function
run_mediation(spec, data; folds, learners, estimator, deltas, n_mc, kwargs...) -> MediationResultCanonical mediation entry point. Dispatches on spec.effect and returns a MediationResult whose table is the δ-grid from run_mediation_grid.
Keyword arguments
estimator::plugin,:onestep, or:tmle; omitted selects:pluginforControlledDirectand:onestepfor the other effectsdeltas: MTP shift grid (defaults to CausalTargeteddefault_deltas())n_mc: nested mediator Monte Carlo draws per unit (default32)folds,learners,parallel,cache_nuisances: Super Learner / cross-fit controls from CausalTargeted
Natural effects with nonempty spec.moc are refused by assert_natural_admissible!. Discrete recode policies skip the δ-grid and return a one-contrast table (delta = NaN).
CausalMediation.run_mediation_grid — Function
run_mediation_grid(data, trt, outcome; covar, mediators, moc, deltas, estimator, effect, kwargs...) -> DataFrameMediation δ-grid as a DataFrame (rows for TE / NDE / NIE × δ × stratum). Supports optional moc intermediate confounders and estimator ∈ (:plugin, :onestep, :tmle). The omitted estimator selects :plugin for ControlledDirect and :onestep otherwise. Controlled direct effects with nonempty moc or explicit :onestep / :tmle are refused.
Prefer run_mediation with a MediationSpec when you already have an identification certificate. Pass effect to select natural / organic / RT / controlled-direct families (default InterventionalMediation()).
CausalMediation.run_mediation_scalar — Function
run_mediation_scalar(data, trt, outcome; mediators, covar, moc, kwargs...) -> DataFrameBinary contrast d0=0 vs d1=1 with NDE / NIE / TE rows. The omitted estimator selects :plugin for ControlledDirect and :onestep otherwise. Controlled direct plug-in rows have NaN SE and confidence limits.
CausalMediation.run_mediation_scalar_ppl — Function
run_mediation_scalar_ppl(data, trt, outcome; mediators, covar, method, kwargs...) -> DataFrameScalar mediation via :eif (default, run_mediation_scalar) or :conjugate_bootstrap. Both accept handle_missing (forwarded).
CausalMediation.run_tmle3_nde — Function
run_tmle3_nde(data, treatment, outcome; baseline, mediators, folds, rng) -> DataFrameCross-fitted SuperLearner interventional NDE with one-step TMLE targeting.
Influence functions and caches
CausalMediation.eif_psi_interventional — Function
eif_psi_interventional(Q̄, Q_at_M, Q_obs, y, H_at, H_am, ρ_am) -> VectorUncentred EIF contributions for ψ(at, am).
CausalMediation.mediator_density_ratio_vs_obs — Function
mediator_density_ratio_vs_obs(m_obs, μ_pol, μ_obs, σ; trunc) -> Vectorg(M|a_pol,·) / g(M|A_obs,·) under independent Gaussian mediator conditionals.
CausalMediation.decompose_mediation_eif — Function
decompose_mediation_eif(ic10, ic00, ic11) -> NamedTupleMap ψ EIF vectors to NDE / NIE / TE uncentred influence contributions.
CausalMediation.MediationFoldCache — Type
MediationFoldCachePer-fold SuperLearner fits reused across δ values. Policy-specific predictions still depend on a_nat / a_shift. Covariate schemas are fitted once on the full analysis frame so categorical columns encode consistently across folds.
CausalMediation.build_mediation_fold_cache — Function
build_mediation_fold_cache(df, outcome, trt, covar, mediators, folds, rng; learners, moc) -> MediationFoldCacheCross-fit Super Learner fits for outcome, mediators, optional moc, and exposure, reused across δ values on a mediation grid.
Diagnostics and synthetics
CausalMediation.mediation_n_mc_sweep — Function
mediation_n_mc_sweep(data, trt, outcome; covar, mediators, n_mc_values, delta, kwargs...) -> DataFrameRe-fit mediation NDE/NIE/TE at a single delta for each n_mc in n_mc_values. Useful for checking whether nested-MC noise dominates inference.
CausalMediation.mediation_stability_summary — Function
mediation_stability_summary(sweep::DataFrame; central_estimands=("TE", "NDE", "NIE")) -> NamedTupleSummarise a mediation_n_mc_sweep table: SE vs n_mc, and whether signs of central estimates are stable across Monte Carlo depths.
CausalMediation.mediation_stability_markdown — Function
mediation_stability_markdown(sweep; title) -> StringRender a Markdown table of TE SEs and sign-stability from a mediation_n_mc_sweep result (via mediation_stability_summary).
CausalMediation.validate_mediation_sweep — Function
validate_mediation_sweep(sweep) -> NamedTupleCheck the minimum evidential contract for a nested-MC mediation result table. This is a validation diagnostic, not a causal identification test: it catches missing columns, invalid Monte Carlo settings and non-finite estimates while leaving exchangeability and positivity to the declared analysis certificate.
CausalMediation.simulate_mediation — Function
simulate_mediation(n; ...) -> (df, truth)Binary-A linear mediation DGP (same as CausalTargeted).
CausalMediation.simulate_continuous_mtp_mediation — Function
simulate_continuous_mtp_mediation(n; ...) -> (df, truth)Continuous-exposure mediation DGP for MTP δ-grids (forwards to CausalTargeted).
CausalMediation.simulate_intermediate_confounding_mediation — Function
simulate_intermediate_confounding_mediation(n; ...) -> (df, truth)Mediation DGP with a post-treatment intermediate confounder L (moc).
CausalMediation.simulate_recanting_twin_mediation — Function
simulate_recanting_twin_mediation(n; ...) -> (df, truth)Two-mediator DGP with a recanting structure: A → M1 → M2 → Y and A → M2, so natural effects are not identified without path-specific (RT) assumptions.
CausalMediation.simulate_categorical_a_mediation — Function
simulate_categorical_a_mediation(n; ...) -> (df, truth)Three-level string exposure A ∈ {0,1,2}, continuous mediator and outcome. Default MTP recodes 2 → 1. Sample interventional oracles:
- NDE = (β{A1} − β{A2}) P(A=2)
- NIE = β_M (γ1 − γ2) P(A=2)
- TE = NDE + NIE
Target trial and Riesz
CausalMediation.TargetTrialMediation — Type
TargetTrialMediationHigh-level constructor over interventional (RI) effects with trial-style policy language (Moreno-Betancur et al. 2021 / medRCT semantics).
CausalMediation.target_trial_mediation — Function
target_trial_mediation(...) -> MediationSpecBuild an interventional MediationSpec from target-trial contrasts. Policies use raw additive shifts of intervention_d0 / intervention_d1 (SD-scale via ShiftPolicy).
CausalMediation.fit_riesz_representer — Function
fit_riesz_representer(X, y; kwargs...) -> AnyFit a Riesz representer for high-dimensional mediators / moc. Requires using Lux so the weakdep extension loads. Without Lux, throws.
CausalMediation.riesz_available — Function
riesz_available() -> BoolReturn true when the Lux extension is loaded.
PPL helpers
CausalMediation.prepare_ppl_mediation_spec — Function
prepare_ppl_mediation_spec(g, treatment, outcome, data, covar, mediators; node_names) -> NamedTuple
prepare_ppl_mediation_spec(treatment, outcome, data, covar, mediators; kwargs...) -> NamedTuplePrepare a NamedTuple for PPL / RxInfer-style mediation workflows. With a graph and node_names, delegates to CausalDynamics prepare_for_rxinfer when available; otherwise returns a generic identifiable spec.
CausalMediation.conjugate_mediation_bootstrap — Function
conjugate_mediation_bootstrap(df, trt, outcome, covar, mediators; n_boot, rng, handle_missing)
-> DataFrameLinear-Gaussian bootstrap NDE / NIE / TE (pedagogical / sensitivity check, not the main EIF path).
Missing outcomes / covariates follow CausalTargeted handle_missing (:drop default). Under :ipcw / :ipcw_impute, bootstrap draws are weighted by the returned observation weights (no silent dropmissing).