#Libraries for causal graphs
library(dagitty) #Identification
library(ggdag) #plotting
library(pcalg) #search
library(gridExtra) #Graph Display

Plans

Structural Causal Models and DAGs, review

Causal Markov Condition

Illustration: Adjustment Formula from Causal Markov

structuregraphs<-list()

confoundgraph<-dagify(Y~X+Z,X~Z) #create graph
#Set position of nodes 
  coords<-list(x=c(X = 0, Z = 1, Y = 2),y=c(X = 0, Z = -0.1, Y = 0)) 
  coords_df<-coords2df(coords)
  coordinates(confoundgraph)<-coords2list(coords_df)
structuregraphs[[1]]<-ggdag(confoundgraph)+theme_dag_blank()+labs(title="Confounding of effect of X on Y by Z") #Plot causal graph
perturbedgraph<-dagify(Y~x+Z) #create graph
#Set position of nodes 
  coords<-list(x=c(x = 0, Z = 1, Y = 2),y=c(x = 0, Z = -0.1, Y = 0)) 
  coords_df<-coords2df(coords)
  coordinates(perturbedgraph)<-coords2list(coords_df)
structuregraphs[[2]]<-ggdag(perturbedgraph)+theme_dag_blank()+labs(title="Perturbed Graph") #Plot causal graph
grid.arrange(grobs=structuregraphs,nrow=1,ncol=2) #Arrange In 1x2 grid

Conditioning and d-separation

edgetypes<-list()
forkgraph<-dagify(Y~Z,X~Z) #create graph
#Set position of nodes 
  coords<-list(x=c(X = 0, Z = 1, Y = 2),y=c(X = 0, Z = 0, Y = 0)) 
  coords_df<-coords2df(coords)
  coordinates(forkgraph)<-coords2list(coords_df)
edgetypes[[1]]<-ggdag(forkgraph)+theme_dag_blank()+labs(title="Fork Structure") #Plot causal graph
chaingraph<-dagify(Y~Z,Z~X) #create graph
#Set position of nodes 
  coords<-list(x=c(X = 0, Z = 1, Y = 2),y=c(X = 0, Z = 0, Y = 0)) 
  coords_df<-coords2df(coords)
  coordinates(chaingraph)<-coords2list(coords_df)
edgetypes[[2]]<-ggdag(chaingraph)+theme_dag_blank()+labs(title="Chain Structure") #Plot causal graph
collidergraph<-dagify(Z~Y,Z~X) #create graph
#Set position of nodes 
  coords<-list(x=c(X = 0, Z = 1, Y = 2),y=c(X = 0, Z = 0, Y = 0)) 
  coords_df<-coords2df(coords)
  coordinates(collidergraph)<-coords2list(coords_df)
edgetypes[[3]]<-ggdag(collidergraph)+theme_dag_blank()+labs(title="Collider structure") #Plot causal graph
grid.arrange(grobs=edgetypes,nrow=3,ncol=1) #Arrange In 3x1 grid

Colliders and Selection

set.seed(123) #Reproduce same simulation each time
observations<-2000
grades<-rnorm(observations)
wealth<-rnorm(observations)
#Grades and wealth influence admission score
admitscore<-grades+wealth+0.3*rnorm(observations) 
#Admit top 10% of applicants by score
threshhold<-quantile(admitscore,0.9)
admission<-(admitscore > threshhold)

#Make plot of conditional and unconditional relationship
simdata<-data.frame(grades,wealth,admission)
ggplot(simdata)+geom_point(aes(x=wealth,y=grades,color=admission))+
  #Regress y on x with no controls
  #lm(grades~wealth)
  geom_smooth(aes(x=wealth,y=grades),method="lm",color="black")+
  #Regress y on x and w (with interaction)
  #lm(grades~wealth+admission+I(wealth*admission))
  geom_smooth(aes(x=wealth,y=grades,group=admission),method="lm",color="blue")+
  labs(title="Grades vs Wealth, with Admission as Collider",
          subtitle="Black Line: Unconditional. Blue Lines: Conditional on Admission")

Causal effects and their identification: do-calculus

  1. Insertion/deletion of observations:
    • If \((Y\perp Z| X,W)_{G_{\bar{X}}}\), \(P(Y|do(X=x),Z=z,W=w)=P(Y|do(X=x),W=w)\)
  2. Action/observation exchange
    • If \((Y\perp Z| X,W)_{G_{\bar{X}\underline{Z}}}\), \(P(Y|do(X=x),do(Z=z),W=w)=P(Y|do(X=x),Z=z,W=w)\)
  3. Insertion/deletion of actions.
    • Let \(Z(W)\) be set of \(Z\) that are not ancestors of \(W\) in \(G_{\bar{X}}\).
    • If \((Y\perp Z| X,W)_{G_{\bar{X}\bar{Z}(W)}}\), \(P(Y|do(X=x),do(Z=z),W=w)=P(Y|do(X=x),W=w)\)

Backdoor Criterion

Backdoor criterion: intuition

#Check if Z satisfies criterion
isAdjustmentSet(graphname,"Z",exposure="X",outcome="Y")
#Find variables that satisfy criterion, if they exist
adjustmentSets(graphname,exposure="X",outcome="Y") 

Example: 1: Conditions for finding adjustment sets

examplegraph<-dagify(Y~A+C,B~X+Y,A~X,X~C,D~B) #create graph
#Set position of nodes 
  coords<-list(x=c(X = 0, A = 1, B = 1, C=1, Y=2, D=2),y=c(X = 0, A = 0.1, B=0, C=-0.1, Y = 0, D=0.1)) 
  coords_df<-coords2df(coords)
  coordinates(examplegraph)<-coords2list(coords_df)
ggdag(examplegraph)+theme_dag_blank()+labs(title="Example Graph") #Plot causal graph

adjustmentSets(examplegraph,exposure="X",outcome="Y")
## { C }

Example 2: Controlling for a descendant

mediatorgraph<-dagify(Y~Z,Z~X) #create graph
#Set position of nodes 
  coords<-list(x=c(X = 0, Z = 1, Y = 2),y=c(X = 0, Z = 0, Y = 0)) 
  coords_df<-coords2df(coords)
  coordinates(mediatorgraph)<-coords2list(coords_df)
ggdag(mediatorgraph)+theme_dag_blank()+labs(title="Mediator structure") #Plot causal graph

Aside: Well-defined or manipulable treatments

Example 3: M-bias: controlling for a collider

mgraph<-m_bias() #A common teaching example, so it has a canned command
ggdag(mgraph)+theme_dag_blank()+labs(title="Graph illustrating m-bias")

adjustmentSets(mgraph,exposure="x",outcome="y",type="all")
##  {}
## { a }
## { b }
## { a, b }
## { a, m }
## { b, m }
## { a, b, m }

Multiple causal effects: the table 2 Fallacy

Example 4: Efficiency: Instrumental Variables and Nonconfounders

irrelevantgraph<-dagitty("dag{Y<-X; Y<-Z1; Y<-Z2; X<-Z2; X<-Z3; Z4}") #create graph
#Set position of nodes 
  coords<-list(x=c(X = 0, Z3 = 0, Z2 = 0.5, Z4 = 0.5, Z1=1, Y=1),y=c(X = 0, Z1 = 0.5, Z2 = 0.25, Z4=0.5, Z3=0.5, Y=0)) 
  coords_df<-coords2df(coords)
  coordinates(irrelevantgraph)<-coords2list(coords_df)
ggdag(irrelevantgraph)+theme_dag_blank()+labs(title="Graph with confounders and more",subtitle = "Z1 affects Y but not X, Z3 affects X not Y, Z2 affects both, Z4 irrelevant") #Plot causal graph

adjustmentSets(irrelevantgraph,exposure="X",outcome="Y",type="all")
## { Z2 }
## { Z1, Z2 }
## { Z2, Z3 }
## { Z1, Z2, Z3 }
## { Z2, Z4 }
## { Z1, Z2, Z4 }
## { Z2, Z3, Z4 }
## { Z1, Z2, Z3, Z4 }

Efficiency vs robustness

Example 5: Chains

sequencegraph<-dagify(Y~X+Z1, Z1~Z2, Z2~Z3, X~Z3) #create graph
#Set position of nodes 
  coords<-list(x=c(X = 0, Z3 = 0, Z2 = 0.5, Z1=1, Y=1),y=c(X = 0, Z1 = 0.5, Z2 = 0.5, Z3=0.5, Y=0)) 
  coords_df<-coords2df(coords)
  coordinates(sequencegraph)<-coords2list(coords_df)
ggdag(sequencegraph)+theme_dag_blank()+labs(title="Graph with confounders in a chain") #Plot causal graph

adjustmentSets(sequencegraph,exposure="X",outcome="Y",type="all")
## { Z1 }
## { Z2 }
## { Z1, Z2 }
## { Z3 }
## { Z1, Z3 }
## { Z2, Z3 }
## { Z1, Z2, Z3 }

Alternative identification strategies

Front Door criterion

Front Door graph

Adding assumptions to Structural Causal Models

Removing assumptions from Structural Causal Models

Estimation

Building and testing your DAG

Software

Library Language Uses/features
dagitty R, online identification
ggdag R identification, plotting
pcalg R discovery, estimation
dowhy Python identification, estimation
ananke Python identification, estimation
causalfusion online identification, estimation, derivation

Conclusion

References

Bareinboim, Elias, and Judea Pearl. 2016. “Causal Inference and the Data-Fusion Problem.” Proceedings of the National Academy of Sciences 113 (27): 7345–52.
Bellemare, Marc F, Jeffrey R Bloem, and Noah Wexler. 2020. “The Paper of How: Estimating Treatment Effects Using the Front-Door Criterion.”
Belloni, Alexandre, Victor Chernozhukov, and Christian Hansen. 2014. “Inference on Treatment Effects After Selection Among High-Dimensional Controls.” The Review of Economic Studies 81 (2): 608–50.
Bertrand, Marianne, and Sendhil Mullainathan. 2004. “Are Emily and Greg More Employable Than Lakisha and Jamal? A Field Experiment on Labor Market Discrimination.” American Economic Review 94 (4): 991–1013.
Bhattacharya, Rohit, Razieh Nabi, and Ilya Shpitser. 2020. “Semiparametric Inference for Causal Effects in Graphical Models with Hidden Variables.” arXiv Preprint arXiv:2003.12659.
Chernozhukov, Victor, Chris Hansen, and Martin Spindler. 2016. “Hdm: High-Dimensional Metrics.” arXiv Preprint arXiv:1608.00354.
Ding, Peng, and Luke W Miratrix. 2015. “To Adjust or Not to Adjust? Sensitivity Analysis of m-Bias and Butterfly-Bias.” Journal of Causal Inference 3 (1): 41–57.
Duarte, Guilherme, Noam Finkelstein, Dean Knox, Jonathan Mummolo, and Ilya Shpitser. 2021. “An Automated Approach to Causal Inference in Discrete Settings.” http://arxiv.org/abs/2109.13471.
Hünermund, Paul, and Elias Bareinboim. 2019. “Causal Inference and Data Fusion in Econometrics.” arXiv Preprint arXiv:1912.09104.
Imbens, Guido W. 2020. “Potential Outcome and Directed Acyclic Graph Approaches to Causality: Relevance for Empirical Practice in Economics.” Journal of Economic Literature 58 (4): 1129–79.
Pearl, Judea. 2009. Causality. Cambridge university press.
Sen, Maya, and Omar Wasow. 2016. “Race as a Bundle of Sticks: Designs That Estimate Effects of Seemingly Immutable Characteristics.” Annual Review of Political Science 19: 499–522.
Witte, Janine, Leonard Henckel, Marloes H Maathuis, and Vanessa Didelez. 2020. “On Efficient Adjustment in Causal Graphs.” Journal of Machine Learning Research 21: 246.
Wright, Sewall. 1934. “The Method of Path Coefficients.” Ann. Math. Statist. 5 (3): 161–215. https://doi.org/10.1214/aoms/1177732676.