RxInfer and GraphPPL integration
CausalDynamics.jl handles identification (backdoor adjustment sets, prepare_for_rxinfer). GraphPPL.jl specifies the observational generative head; RxInfer.jl runs variational message-passing inference.
Load the extension:
using CausalDynamics
using RxInfer # activates CausalDynamicsRxInferWorkflow
- Build a DAG and attach tabular data (
DataFrameorNamedTuple). prepare_for_rxinfer(g, X, Y; node_names=...)— confounders + identifiability flag.infer_backdoor_effect(g, data, X, Y; ...)— Frisch–Waugh partialing in Julia, then a conjugate GraphPPL head and VI forτ.
Confounders in the identified adjustment set are partialled out of outcome and treatment (residualise_backdoor) so the RxInfer head is a single conjugate slope τ on residualised (y, x). A full multi-coefficient GraphPPL regression with latent β vectors is reserved for a later release (non-conjugate without custom initialisation).
using CausalDynamics, RxInfer, Graphs, DataFrames, Random
g = DiGraph(3)
add_edge!(g, 1, 2)
add_edge!(g, 1, 3)
add_edge!(g, 2, 3)
names = Dict(1 => :Z, 2 => :X, 3 => :Y)
data = DataFrame(Z=randn(100), X=randn(100), Y=randn(100))
result = infer_backdoor_effect(g, data, 2, 3; node_names=names)
result.τ_mean # posterior mean; do not use Statistics.mean(result.τ_posterior)See examples/rxinfer_backdoor.jl in the package root.
API
| Function | Role |
|---|---|
has_rxinfer() | Extension loaded? |
prepare_for_rxinfer | Identification bridge (always available) |
residualise_backdoor | Frisch–Waugh partialing of (y, x) on confounders |
backdoor_graphppl_model | GraphPPL @model generator (backdoor_gaussian_ate) |
ppl_data_from_spec | Tabular → residualised RxInfer data tuple |
infer_backdoor_effect | Full identify + partial + infer pipeline |
posterior_mean_τ | Scalar mean from τ_posterior marginals |
Process vs Pearl naming
Package APIs stay in Pearl / SciML vocabulary. For a process-metaphysics gloss used in the CDCS book, see the book’s Concept Reference (Table 8), not this package manual.
Dependencies
Optional weak dependencies: GraphPPL, RxInfer. They are not required for core CausalDynamics or the CDCS book Project.toml.
If Pkg.resolve() fails after adding RxInfer, cap Graphs at 1.13 in your application environment (RxInfer 5.x vs DataStructures 0.19). See AgeSCM docs/RXINFER_DEPS.md for a resolved stack example.
Further reading
- RxInfer docs
- GraphPPL docs
- TMLE integration for doubly robust estimation