DAG and potential outcomes frameworks for causal mediation identification
Identification Theory
Comprehensive framework for causal identification in statistical methodology
Use this skill when working on: causal identification, mediation analysis identification, DAG-based reasoning, potential outcomes, identification assumptions, partial identification, sensitivity analysis, or deriving identification formulas.
Core Concepts
What is Identification?
A causal parameter $\psi$ is identified if it can be uniquely determined from the observed data distribution $P(O)$.
Formally: $\psi$ is identified if $P_1(O) = P_2(O) \Rightarrow \psi_1 = \psi_2$.
Why Identification Matters
Causal Question → Target Estimand → Identification → Estimation → Inference
↓ ↓ ↓ ↓ ↓
"Does A E[Y(1)-Y(0)] Express in Statistical Confidence
cause Y?" terms of P(O) methods intervals
Without identification, no amount of data can answer causal questions.
Two Frameworks
1. Potential Outcomes (Rubin/Neyman)
Primitives:
$Y(a)$ = potential outcome under treatment $a$
Only $Y = Y(A)$ is observed (consistency)
Fundamental problem: never observe both $Y(0)$ and $Y(1)$ for same unit
Clear separation of statistical and causal assumptions
DAG Framework
Directed Acyclic Graphs (DAGs)
A DAG $\mathcal{G} = (V, E)$ consists of:
Vertices $V$: Random variables
Directed edges $E$: Direct causal relationships
Acyclic: No directed cycles
Key DAG Terminology
Term
Definition
Notation
Parents
Direct causes
$PA_Y$
Children
Direct effects
$CH_Y$
Ancestors
All causes
$AN_Y$
Descendants
All effects
$DE_Y$
Collider
Node with two incoming arrows
$A \to C \leftarrow B$
Mediator
Node on causal path
$A \to M \to Y$
Confounder
Common cause
$A \leftarrow C \to Y$
# DAG specification and visualization using dagitty
library(dagitty)# Define mediation DAG
mediation_dag <- dagitty('
dag {
A [exposure]
M [mediator]
Y [outcome]
X [confounder]
X -> A
X -> M
X -> Y
A -> M
A -> Y
M -> Y
}
')# Visualize
plot(mediation_dag)# Find adjustment sets
adjustmentSets(mediation_dag, exposure ="A", outcome ="Y")# Check implied conditional independencies
impliedConditionalIndependencies(mediation_dag)
D-Separation
The Core Concept
Two nodes $A$ and $B$ are d-separated by set $Z$ if every path between them is blocked.
Path Blocking Rules
Path Type
Blocked by conditioning on...
Chain: $A \to M \to B$
$M$ (blocks)
Fork: $A \leftarrow C \to B$
$C$ (blocks)
Collider: $A \to C \leftarrow B$
NOT $C$ (conditioning opens!)
D-separation Formula
$$A \perp!!!\perp_{\mathcal{G}} B \mid Z \iff \text{every path } A \text{---} B \text{ is blocked by } Z$$
# Check d-separation using dagitty
check_dseparation <-function(dag, x, y, z =NULL){if(is.null(z)){
dseparated(dag, x, y)}else{
dseparated(dag, x, y, z)}}# Find all d-separating sets
find_dsep_sets <-function(dag, x, y){# All adjustment sets that d-separate x and y
adjustmentSets(dag, exposure = x, outcome = y, effect ="total")}# Verify conditional independence implications
verify_ci_implications <-function(dag, data){
implied_ci <- impliedConditionalIndependencies(dag)
results <- lapply(implied_ci,function(ci){# Parse the CI statement
vars <- strsplit(as.character(ci)," _\\|\\|_ | \\| ")[[1]]
x <- vars[1]
y <- vars[2]
z <-if(length(vars)>2) vars[3:length(vars)]elseNULL# Test with partial correlation or conditional independence test
test_result <- test_conditional_independence(data, x, y, z)list(statement =as.character(ci), p_value = test_result$p.value)})
do.call(rbind, lapply(results, as.data.frame))}
Backdoor Criterion
Definition
A set $Z$ satisfies the backdoor criterion relative to $(A, Y)$ if:
No node in $Z$ is a descendant of $A$
$Z$ blocks every path between $A$ and $Y$ that contains an arrow into $A$
Backdoor Adjustment Formula
If $Z$ satisfies the backdoor criterion:
$$P(Y | do(A = a)) = \sum_z P(Y | A = a, Z = z) P(Z = z)$$
or equivalently:
$$E[Y(a)] = E_Z[E[Y | A = a, Z]]$$
Front-Door Criterion
When backdoor fails but mediator is unconfounded:
$$P(Y | do(A)) = \sum_m P(M = m | A) \sum_{a'} P(Y | M = m, A = a') P(A = a')$$