16. Notebook-DAGitty#
install.packages("dagitty")
install.packages("ggdag")
library(dagitty)
library(ggdag)
16.1. Graph Generation and Plotting#
The following DAG is due to Judea Pearl
#generate a couple of DAGs and plot them
G = dagitty('dag{
Z1 [pos="-2,-1.5"]
X1 [pos="-2,0"]
Z2 [pos="1.5,-1.5"]
X3 [pos="1.5, 0"]
Y [outcome,pos="1.5,1.5"]
D [exposure,pos="-2,1.5"]
M [mediator, pos="0,1.5"]
X2 [pos="0,0"]
Z1 -> X1
X1 -> D
Z1 -> X2
Z2 -> X3
X3 -> Y
Z2 -> X2
D -> Y
X2 -> Y
X2 -> D
M->Y
D->M
}')
ggdag(G)+ theme_dag()
Error in ggdag(G): could not find function "ggdag"
Traceback:
Report Relatives of X2
print(parents(G, "X2"))
print(children(G, "X2"))
print(ancestors(G, "X2"))
print(descendants(G, "X2"))
Find Paths Between D and Y
paths(G, "D", "Y")
List All Testable Implications of the Model
print( impliedConditionalIndependencies(G) )
Identification by Backdoor: List minimal adjustment sets to identify causal effecs \(D \to Y\)
print( adjustmentSets( G, "D", "Y" ) )
Identification via SWIG and D-separation
SWIG = dagitty('dag{
Z1 [pos="-2,-1.5"]
X1 [pos="-2,0"]
Z2 [pos="1.5,-1.5"]
X3 [pos="1.5, 0"]
Yd [outcome,pos="1.5,1.5"]
D [exposure,pos="-2,1.5"]
d [pos="-1, 1.5"]
Md [mediator, pos="0,1.5"]
X2 [pos="0,0"]
Z1 -> X1
X1 -> D
Z1 -> X2
Z2 -> X3
X3 -> Yd
Z2 -> X2
X2 -> Yd
X2 -> D
X3-> Yd
Md-> Yd
d-> Md
}')
ggdag(SWIG)+ theme_dag()
Deduce Conditional Exogeneity or Ignorability by D-separation
print( impliedConditionalIndependencies(SWIG)[5:8] )
This coincides with the backdoor criterion for this graph.
Print All Average Effects Identifiable by Conditioning
for( n in names(G) ){
for( m in children(G,n) ){
a <- adjustmentSets( G, n, m )
if( length(a) > 0 ){
cat("The effect ",n,"->",m,
" is identifiable by controlling for:\n",sep="")
print( a, prefix=" * " )
}
}
}
Equivalence Classes
P=equivalenceClass(G)
plot(P)
#equivalentDAGs(G,10)
Next Consider the elemntary Triangular Model:
This model has not testable implications and is Markov-equivalent to any other DAG difined on names \((X, D, Y)\).
G3<- dagitty('dag{
D -> Y
X -> D
X -> Y
}
')
ggdag(G3)+ theme_dag()
print(impliedConditionalIndependencies(G3))
P=equivalenceClass(G3)
plot(P)
equivalentDAGs(G3,10)
16.2. Example of Testing DAG Validity#
Next we simulate the data from a Linear SEM associated to DAG G, and perform a test of conditional independence restrictions, exploting linearity.
There are many other options for nonlinear models and discrete categorical variabales. Type help(localTests).
set.seed(1)
x <- simulateSEM(G)
head(x)
#cov(x)
localTests(G, data = x, type = c("cis"))
Next we replaced \(D\) by \(\bar D\) generated differently:
So basically \(\bar D\) is an average of \(D\) and \(Y\) generated by \(D\). We then test if the resulting collection of random variables satisifes conditional indepdendence restrictions, exploiting linearity. We end up rejectiong these restrictions and thefore the validity of this model for the data generated in this way. This makes sense, because the new data no longer obeys the previous DAG structure.
x.R = x
x.R$D = (x$D+ x$Y)/2
localTests(G, data = x.R, type = c("cis"))