2 min read

Adjustment set exercise from Elwert 2013

Load packages

library(tidyverse)
library(ggdag)
library(dagitty)

Define DAG

I’ve drawn the DAG in dagitty.net, that’s why the coordinates look weird.

dag3_str <- '
dag {
bb="-2.865,-5.146,2.956,4.896"
U [latet, pos="2.456,-0.958"]
X [exposure, pos="-2.365,-4.309"]
Y [outcome, pos="-0.271,4.059"]
Z1 [pos="-0.491,-1.925"]
Z2 [pos="-0.915,1.269"]
Z3 [pos="1.713,1.984"]
U -> Z1
U -> Z3
X -> Z1
Z2 -> Y
Z2 -> Z1
Z2 -> Z3
Z3 -> Y
}'

Then tidify:

dag3 <- dagitty(dag3_str)

dag3_tidy <- tidy_dagitty(dag3)

dag3_tidy
#> # A DAG with 6 nodes and 7 edges
#> #
#> # Exposure: X
#> # Outcome: Y
#> #
#> # A tibble: 9 x 8
#>   name       x      y direction to      xend  yend circular
#>   <chr>  <dbl>  <dbl> <fct>     <chr>  <dbl> <dbl> <lgl>   
#> 1 U      2.46  -0.958 ->        Z1    -0.491 -1.92 FALSE   
#> 2 U      2.46  -0.958 ->        Z3     1.71   1.98 FALSE   
#> 3 X     -2.37  -4.31  ->        Z1    -0.491 -1.92 FALSE   
#> 4 Z2    -0.915  1.27  ->        Y     -0.271  4.06 FALSE   
#> 5 Z2    -0.915  1.27  ->        Z1    -0.491 -1.92 FALSE   
#> 6 Z2    -0.915  1.27  ->        Z3     1.71   1.98 FALSE   
#> 7 Z3     1.71   1.98  ->        Y     -0.271  4.06 FALSE   
#> 8 Z1    -0.491 -1.92  <NA>      <NA>  NA     NA    FALSE   
#> 9 Y     -0.271  4.06  <NA>      <NA>  NA     NA    FALSE

Plot

ggdag(dag3_tidy) + theme_dag()

Find adjustment sets

Which paths need be closed in order to get the causal effect of \(X\) on \(Y\)?

ggdag_adjustment_set(dag3_tidy, node_size = 14) + 
  theme_dag(legend.position = "bottom")

No need to control for any variable!

Controlling for Z1

dag3_tidy %>% 
  ggdag_dseparated(from = "X", to = "Y", controlling_for = "Z1")

If we control for \(Z1\), a bunch of paths fom \(X\) to \(Y\) get openened, as can be seen in the DAG:

  1. X - Z1 - U - Z3 - Y
  2. X - Z1 - Z2 - Y
  3. X - Z1 - Z2 - Y

As a consequence, we have open backdoors from \(X\) to \(Y\). The causal effect is now confounded by these additional back doors.