What are they?
- Simple representations of structural models
- Without “cycles” (directed acyclic graph)
- These allow us to apply some graph theory tricks to statistics
- Grew out of the work of Judea Pearl
2/1/2020
What are they?
Why teach with causal diagrams?
What are the difficulties?
For resources, difficult to recommend Pearl too much directly, as his writing is generally not targeted at economists/meeting us where we are. But:
All of this is dependent on the idea of one variable causing another? So what’s our working definition of that?
It’s based on the do-operator from the do-calculus. Iff we could set the value of a variable X, and as a result Y changes, then X causes Y.
Let’s make some models!
We’re economists, we know this one.
What variables are likely in the DGP for crime? (simplified)
What causes what?
“ Front doors”! These are the effects we’re interested in. Rules for picking these may vary depending on research Q (maybe the second doesn’t count!)
Closed doors (back to this in a bit)
This paths approach does a few things pedagogically:
cor(Police,Crime)
we get the effects we want, but ALSO all the effects that go along the back door paths. This is both more precise and more intuitive than “OVB is from variables related to both treatment and outcome”. We are interested only in the part of the correlation that we can identify as being due to our front door paths.Closed doors
Controlling for L.Crime
Closed doors
Controlling for L.Crime and LawOrd
Closed doors
cor(MomEyes,DadEyes) = 0
without adjustmentTrue relationship is 0…
Just interviewing tech workers is similar to “controlling for tech”
## List of 65 ## $ line :List of 6 ## ..$ colour : chr "black" ## ..$ size : num 0.5 ## ..$ linetype : num 1 ## ..$ lineend : chr "butt" ## ..$ arrow : logi FALSE ## ..$ inherit.blank: logi TRUE ## ..- attr(*, "class")= chr [1:2] "element_line" "element" ## $ rect :List of 5 ## ..$ fill : chr "white" ## ..$ colour : chr "black" ## ..$ size : num 0.5 ## ..$ linetype : num 1 ## ..$ inherit.blank: logi TRUE ## ..- attr(*, "class")= chr [1:2] "element_rect" "element" ## $ text :List of 11 ## ..$ family : chr "" ## ..$ face : chr "plain" ## ..$ colour : chr "black" ## ..$ size : num 11 ## ..$ hjust : num 0.5 ## ..$ vjust : num 0.5 ## ..$ angle : num 0 ## ..$ lineheight : num 0.9 ## ..$ margin : 'margin' num [1:4] 0pt 0pt 0pt 0pt ## .. ..- attr(*, "valid.unit")= int 8 ## .. ..- attr(*, "unit")= chr "pt" ## ..$ debug : logi FALSE ## ..$ inherit.blank: logi TRUE ## ..- attr(*, "class")= chr [1:2] "element_text" "element" ## $ axis.title.x :List of 11 ## ..$ family : NULL ## ..$ face : NULL ## ..$ colour : NULL ## ..$ size : NULL ## ..$ hjust : NULL ## ..$ vjust : num 1 ## ..$ angle : NULL ## ..$ lineheight : NULL ## ..$ margin : 'margin' num [1:4] 2.75pt 0pt 0pt 0pt ## .. ..- attr(*, "valid.unit")= int 8 ## .. ..- attr(*, "unit")= chr "pt" ## ..$ debug : NULL ## ..$ inherit.blank: logi TRUE ## ..- attr(*, "class")= chr [1:2] "element_text" "element" ## $ axis.title.x.top :List of 11 ## ..$ family : NULL ## ..$ face : NULL ## ..$ colour : NULL ## ..$ size : NULL ## ..$ hjust : NULL ## ..$ vjust : num 0 ## ..$ angle : NULL ## ..$ lineheight : NULL ## ..$ margin : 'margin' num [1:4] 0pt 0pt 2.75pt 0pt ## .. ..- attr(*, "valid.unit")= int 8 ## .. ..- attr(*, "unit")= chr "pt" ## ..$ debug : NULL ## ..$ inherit.blank: logi TRUE ## ..- attr(*, "class")= chr [1:2] "element_text" "element" ## $ axis.title.y :List of 11 ## ..$ family : NULL ## ..$ face : NULL ## ..$ colour : NULL ## ..$ size : NULL ## ..$ hjust : NULL ## ..$ vjust : num 1 ## ..$ angle : num 90 ## ..$ lineheight : NULL ## ..$ margin : 'margin' num [1:4] 0pt 2.75pt 0pt 0pt ## .. ..- attr(*, "valid.unit")= int 8 ## .. ..- attr(*, "unit")= chr "pt" ## ..$ debug : NULL ## ..$ inherit.blank: logi TRUE ## ..- attr(*, "class")= chr [1:2] "element_text" "element" ## $ axis.title.y.right :List of 11 ## ..$ family : NULL ## ..$ face : NULL ## ..$ colour : NULL ## ..$ size : NULL ## ..$ hjust : NULL ## ..$ vjust : num 0 ## ..$ angle : num -90 ## ..$ lineheight : NULL ## ..$ margin : 'margin' num [1:4] 0pt 0pt 0pt 2.75pt ## .. ..- attr(*, "valid.unit")= int 8 ## .. ..- attr(*, "unit")= chr "pt" ## ..$ debug : NULL ## ..$ inherit.blank: logi TRUE ## ..- attr(*, "class")= chr [1:2] "element_text" "element" ## $ axis.text :List of 11 ## ..$ family : NULL ## ..$ face : NULL ## ..$ colour : chr "grey30" ## ..$ size : 'rel' num 0.8 ## ..$ hjust : NULL ## ..$ vjust : NULL ## ..$ angle : NULL ## ..$ lineheight : NULL ## ..$ margin : NULL ## ..$ debug : NULL ## ..$ inherit.blank: logi TRUE ## ..- attr(*, "class")= chr [1:2] "element_text" "element" ## $ axis.text.x :List of 11 ## ..$ family : NULL ## ..$ face : NULL ## ..$ colour : NULL ## ..$ size : NULL ## ..$ hjust : NULL ## ..$ vjust : num 1 ## ..$ angle : NULL ## ..$ lineheight : NULL ## ..$ margin : 'margin' num [1:4] 2.2pt 0pt 0pt 0pt ## .. ..- attr(*, "valid.unit")= int 8 ## .. ..- attr(*, "unit")= chr "pt" ## ..$ debug : NULL ## ..$ inherit.blank: logi TRUE ## ..- attr(*, "class")= chr [1:2] "element_text" "element" ## $ axis.text.x.top :List of 11 ## ..$ family : NULL ## ..$ face : NULL ## ..$ colour : NULL ## ..$ size : NULL ## ..$ hjust : NULL ## ..$ vjust : num 0 ## ..$ angle : NULL ## ..$ lineheight : NULL ## ..$ margin : 'margin' num [1:4] 0pt 0pt 2.2pt 0pt ## .. ..- attr(*, "valid.unit")= int 8 ## .. ..- attr(*, "unit")= chr "pt" ## ..$ debug : NULL ## ..$ inherit.blank: logi TRUE ## ..- attr(*, "class")= chr [1:2] "element_text" "element" ## $ axis.text.y :List of 11 ## ..$ family : NULL ## ..$ face : NULL ## ..$ colour : NULL ## ..$ size : NULL ## ..$ hjust : num 1 ## ..$ vjust : NULL ## ..$ angle : NULL ## ..$ lineheight : NULL ## ..$ margin : 'margin' num [1:4] 0pt 2.2pt 0pt 0pt ## .. ..- attr(*, "valid.unit")= int 8 ## .. ..- attr(*, "unit")= chr "pt" ## ..$ debug : NULL ## ..$ inherit.blank: logi TRUE ## ..- attr(*, "class")= chr [1:2] "element_text" "element" ## $ axis.text.y.right :List of 11 ## ..$ family : NULL ## ..$ face : NULL ## ..$ colour : NULL ## ..$ size : NULL ## ..$ hjust : num 0 ## ..$ vjust : NULL ## ..$ angle : NULL ## ..$ lineheight : NULL ## ..$ margin : 'margin' num [1:4] 0pt 0pt 0pt 2.2pt ## .. ..- attr(*, "valid.unit")= int 8 ## .. ..- attr(*, "unit")= chr "pt" ## ..$ debug : NULL ## ..$ inherit.blank: logi TRUE ## ..- attr(*, "class")= chr [1:2] "element_text" "element" ## $ axis.ticks : list() ## ..- attr(*, "class")= chr [1:2] "element_blank" "element" ## $ axis.ticks.length : 'unit' num 2.75pt ## ..- attr(*, "valid.unit")= int 8 ## ..- attr(*, "unit")= chr "pt" ## $ axis.ticks.length.x : NULL ## $ axis.ticks.length.x.top : NULL ## $ axis.ticks.length.x.bottom: NULL ## $ axis.ticks.length.y : NULL ## $ axis.ticks.length.y.left : NULL ## $ axis.ticks.length.y.right : NULL ## $ axis.line : list() ## ..- attr(*, "class")= chr [1:2] "element_blank" "element" ## $ axis.line.x : NULL ## $ axis.line.y : NULL ## $ legend.background : list() ## ..- attr(*, "class")= chr [1:2] "element_blank" "element" ## $ legend.margin : 'margin' num [1:4] 5.5pt 5.5pt 5.5pt 5.5pt ## ..- attr(*, "valid.unit")= int 8 ## ..- attr(*, "unit")= chr "pt" ## $ legend.spacing : 'unit' num 11pt ## ..- attr(*, "valid.unit")= int 8 ## ..- attr(*, "unit")= chr "pt" ## $ legend.spacing.x : NULL ## $ legend.spacing.y : NULL ## $ legend.key : list() ## ..- attr(*, "class")= chr [1:2] "element_blank" "element" ## $ legend.key.size : 'unit' num 1.2lines ## ..- attr(*, "valid.unit")= int 3 ## ..- attr(*, "unit")= chr "lines" ## $ legend.key.height : NULL ## $ legend.key.width : NULL ## $ legend.text :List of 11 ## ..$ family : NULL ## ..$ face : NULL ## ..$ colour : NULL ## ..$ size : 'rel' num 0.8 ## ..$ hjust : NULL ## ..$ vjust : NULL ## ..$ angle : NULL ## ..$ lineheight : NULL ## ..$ margin : NULL ## ..$ debug : NULL ## ..$ inherit.blank: logi TRUE ## ..- attr(*, "class")= chr [1:2] "element_text" "element" ## $ legend.text.align : NULL ## $ legend.title :List of 11 ## ..$ family : NULL ## ..$ face : NULL ## ..$ colour : NULL ## ..$ size : NULL ## ..$ hjust : num 0 ## ..$ vjust : NULL ## ..$ angle : NULL ## ..$ lineheight : NULL ## ..$ margin : NULL ## ..$ debug : NULL ## ..$ inherit.blank: logi TRUE ## ..- attr(*, "class")= chr [1:2] "element_text" "element" ## $ legend.title.align : NULL ## $ legend.position : chr "right" ## $ legend.direction : NULL ## $ legend.justification : chr "center" ## $ legend.box : NULL ## $ legend.box.margin : 'margin' num [1:4] 0cm 0cm 0cm 0cm ## ..- attr(*, "valid.unit")= int 1 ## ..- attr(*, "unit")= chr "cm" ## $ legend.box.background : list() ## ..- attr(*, "class")= chr [1:2] "element_blank" "element" ## $ legend.box.spacing : 'unit' num 11pt ## ..- attr(*, "valid.unit")= int 8 ## ..- attr(*, "unit")= chr "pt" ## $ panel.background : list() ## ..- attr(*, "class")= chr [1:2] "element_blank" "element" ## $ panel.border : list() ## ..- attr(*, "class")= chr [1:2] "element_blank" "element" ## $ panel.spacing : 'unit' num 5.5pt ## ..- attr(*, "valid.unit")= int 8 ## ..- attr(*, "unit")= chr "pt" ## $ panel.spacing.x : NULL ## $ panel.spacing.y : NULL ## $ panel.grid :List of 6 ## ..$ colour : chr "grey92" ## ..$ size : NULL ## ..$ linetype : NULL ## ..$ lineend : NULL ## ..$ arrow : logi FALSE ## ..$ inherit.blank: logi TRUE ## ..- attr(*, "class")= chr [1:2] "element_line" "element" ## $ panel.grid.minor :List of 6 ## ..$ colour : NULL ## ..$ size : 'rel' num 0.5 ## ..$ linetype : NULL ## ..$ lineend : NULL ## ..$ arrow : logi FALSE ## ..$ inherit.blank: logi TRUE ## ..- attr(*, "class")= chr [1:2] "element_line" "element" ## $ panel.ontop : logi FALSE ## $ plot.background : list() ## ..- attr(*, "class")= chr [1:2] "element_blank" "element" ## $ plot.title :List of 11 ## ..$ family : NULL ## ..$ face : NULL ## ..$ colour : NULL ## ..$ size : 'rel' num 1.2 ## ..$ hjust : num 0 ## ..$ vjust : num 1 ## ..$ angle : NULL ## ..$ lineheight : NULL ## ..$ margin : 'margin' num [1:4] 0pt 0pt 5.5pt 0pt ## .. ..- attr(*, "valid.unit")= int 8 ## .. ..- attr(*, "unit")= chr "pt" ## ..$ debug : NULL ## ..$ inherit.blank: logi TRUE ## ..- attr(*, "class")= chr [1:2] "element_text" "element" ## $ plot.subtitle :List of 11 ## ..$ family : NULL ## ..$ face : NULL ## ..$ colour : NULL ## ..$ size : NULL ## ..$ hjust : num 0 ## ..$ vjust : num 1 ## ..$ angle : NULL ## ..$ lineheight : NULL ## ..$ margin : 'margin' num [1:4] 0pt 0pt 5.5pt 0pt ## .. ..- attr(*, "valid.unit")= int 8 ## .. ..- attr(*, "unit")= chr "pt" ## ..$ debug : NULL ## ..$ inherit.blank: logi TRUE ## ..- attr(*, "class")= chr [1:2] "element_text" "element" ## $ plot.caption :List of 11 ## ..$ family : NULL ## ..$ face : NULL ## ..$ colour : NULL ## ..$ size : 'rel' num 0.8 ## ..$ hjust : num 1 ## ..$ vjust : num 1 ## ..$ angle : NULL ## ..$ lineheight : NULL ## ..$ margin : 'margin' num [1:4] 5.5pt 0pt 0pt 0pt ## .. ..- attr(*, "valid.unit")= int 8 ## .. ..- attr(*, "unit")= chr "pt" ## ..$ debug : NULL ## ..$ inherit.blank: logi TRUE ## ..- attr(*, "class")= chr [1:2] "element_text" "element" ## $ plot.tag :List of 11 ## ..$ family : NULL ## ..$ face : NULL ## ..$ colour : NULL ## ..$ size : 'rel' num 1.2 ## ..$ hjust : num 0.5 ## ..$ vjust : num 0.5 ## ..$ angle : NULL ## ..$ lineheight : NULL ## ..$ margin : NULL ## ..$ debug : NULL ## ..$ inherit.blank: logi TRUE ## ..- attr(*, "class")= chr [1:2] "element_text" "element" ## $ plot.tag.position : chr "topleft" ## $ plot.margin : 'margin' num [1:4] 5.5pt 5.5pt 5.5pt 5.5pt ## ..- attr(*, "valid.unit")= int 8 ## ..- attr(*, "unit")= chr "pt" ## $ strip.background : list() ## ..- attr(*, "class")= chr [1:2] "element_blank" "element" ## $ strip.placement : chr "inside" ## $ strip.text :List of 11 ## ..$ family : NULL ## ..$ face : NULL ## ..$ colour : chr "grey10" ## ..$ size : 'rel' num 0.8 ## ..$ hjust : NULL ## ..$ vjust : NULL ## ..$ angle : NULL ## ..$ lineheight : NULL ## ..$ margin : 'margin' num [1:4] 4.4pt 4.4pt 4.4pt 4.4pt ## .. ..- attr(*, "valid.unit")= int 8 ## .. ..- attr(*, "unit")= chr "pt" ## ..$ debug : NULL ## ..$ inherit.blank: logi TRUE ## ..- attr(*, "class")= chr [1:2] "element_text" "element" ## $ strip.text.x : NULL ## $ strip.text.y :List of 11 ## ..$ family : NULL ## ..$ face : NULL ## ..$ colour : NULL ## ..$ size : NULL ## ..$ hjust : NULL ## ..$ vjust : NULL ## ..$ angle : num -90 ## ..$ lineheight : NULL ## ..$ margin : NULL ## ..$ debug : NULL ## ..$ inherit.blank: logi TRUE ## ..- attr(*, "class")= chr [1:2] "element_text" "element" ## $ strip.switch.pad.grid : 'unit' num 2.75pt ## ..- attr(*, "valid.unit")= int 8 ## ..- attr(*, "unit")= chr "pt" ## $ strip.switch.pad.wrap : 'unit' num 2.75pt ## ..- attr(*, "valid.unit")= int 8 ## ..- attr(*, "unit")= chr "pt" ## - attr(*, "class")= chr [1:2] "theme" "gg" ## - attr(*, "complete")= logi TRUE ## - attr(*, "validate")= logi TRUE
Identifying by adjustment isn’t limited to selection-on-observables. For example, when does fixed effects work? When the diagram looks like this (after removing any other controlled variables):
Where Indiv is any individual effect that is fixed over time
When does an event study work? When the diagram looks like this
If we think there’s a time effect as well, we either need to account for it with time-series dependencies in an event study, or add a control group so we can directly control for time in DID/Synth
This works if you control for V
Controlling for Run, Above is an IV for Treat (RD relies on a functional form restriction, so this one’s a bit cheaty!)
Say we only want the indirect effect and L.Crime is unmeasurable. Control for Sntnc or LawOrd to get Police \(\rightarrow\) Profit, and control for Police and Sntnc to get Profit \(\rightarrow\) Crime. Combine to get effect.
All paths between LawOrd and L.Crime have colliders. If their raw relationship is nonzero, this model is wrong!
Do we have serial correlation?
Conclusion and Logistics
So if you’re sold, how do you actually make these things?
dev='CairoPNG'
in your code chunklibrary(dagitty); library(ggdag) dag <- dagify(Y2~Y1+Shock2, Y1~Shock1, coords=list( x = c(Y1 = 1, Shock1 = 1.5, Y2 = 1.5, Shock2 = 2), y = c(Y1 = 2, Shock1 = 2.5, Y2 = 1.5, Shock2 = 2) )) %>% tidy_dagitty() ggdag(dag,node_size=20)+theme_void()