How CausalDynamics compares

CausalDynamics.jl owns identify → intervene → shared-U counterfactual trajectories for structural and discrete-time dynamical models. It composes with Julia neighbours and sits next to familiar R/Python graph tools—without trying to replace every CRAN or PyPI package.

Choose CausalDynamics when you need typed identification certificates, discrete-time CDMs, temporal unrolling, or SciML-backed continuous CDMs in the same language as estimation and plotting downstream.

Prefer dagitty / DoWhy when you want a GUI-first workflow, an existing Python four-step pipeline, or discovery-heavy tooling you already trust (Associations.jl and causal-learn remain better homes for full discovery).

Stack overview (integration as the product): ECOSYSTEM_COMPARISON.md.

flowchart LR
  subgraph juliaStack [Julia_typed_pipeline]
    G[Graph_CDM] --> ID[identify_certificate]
    ID --> SIM[simulate_counterfactual]
    ID --> EST[LMTP_mediation]
    ID --> PLOT[DAGMakie]
    SIM --> EST
  end

Legend

MarkMeaning
YesFirst-class, documented
PartialPossible with glue or a limited API
Not in that package’s usual scope
UniqueStrong differentiator here

Julia neighbours

CausalDynamics composes with, rather than competes against, the packages below.

NeedReach forWhy
Learn a DAG from data (PC, OCE)Associations.jlOptional weakdep bridge (infer_pc_graph, infer_oce_temporal_spec); see Associations integration
Learn a DAG from data (legacy Julia PC)CausalInference.jlpcalg; we use CausalInference for d-separation and backdoor primitives
Solve ODEs / SDEs / UDEsSciML, UniversalDiffEq.jlWe supply structure and do(·) semantics, not integrators — see SciML recipes
Continuous MTP / LMTP estimationCausalTargeted.jlConsumes IdentificationResult; see its comparison
Doubly robust point-treatment TMLETMLE.jlWe identify the adjustment set; TMLE estimates (integration)
Scalable Bayesian inferenceRxInfer.jlVariational backdoor head is a weakdep extension
Tabular causal simulation / estimationCausalTables.jlTable-centric; we are trajectory-centric over occasions t = 1:T
DAG figuresDAGMakie.jlOptional plots; comparison

Versus R and Python (graphs / ID / dynamics)

CapabilityCausalDynamicsRPython
d-separation / backdoor / frontdoor / IVYesYes (dagitty, ggdag)Yes (DoWhy, causal-learn)
Typed identify → certificateUnique (IdentificationResult)Partial (dagitty objects + glue)Partial (DoWhy identify result)
Path mediators / minimal mediator cutsYesPartialPartial
Static SCM + do + shared-U CFYes (GraphSCM)Partial (simcausal, limited)Partial (DoWhy SCM)
Discrete-time CDM trajectoriesUnique— / Partial— / Partial
Temporal unroll + time-indexed IDUniquePartial (manual)Partial (custom)
Continuous CDM + SciML doUniquePartial (custom SciPy)
Structure discovery (full algorithms)Partial (bridges)Yes (pcalg, bnlearn)Yes (causal-learn)
Broad four-step estimate API— (estimation is CausalTargeted / TMLE.jl)PartialYes (DoWhy)

What is distinctive here

  • Trajectories, not single outcomessimulate returns a CDMTrajectory with the realised exogenous draws retained
  • Shared-U counterfactual pathscounterfactual replays the same exogenous draws under a different intervention
  • Time-indexed identificationunroll_temporal_dag turns a lag specification into a static DAG so ordinary backdoor logic covers lagged confounding
  • Soft interventionsPolicy supports treatment rules that react to state
  • Lean core — hard dependencies are Graphs and CausalInference only

What is deliberately absent

Full causal discovery implementations, differential-equation solvers, and full symbolic do-calculus. Discovery runs in Associations.jl; identification and trajectories stay here. See Scope.

The CDCS book is the long-form narrative companion for these APIs.