Continuing with our Causal Week Brown Bag Sessions, this is a quick series of activities to get us comfortable with dagitty and ggdag functionality. Here, we’re going to:
DISCLAIMER: this is very brief and in no way comprehensive of the functionality of dagitty or ggdag. See references for further review materials.
Souce code: Github
An easy way to create dags online is on the dagitty website.
As you can see from the home page, Dagitty is developed and maintained by Johannes Textor (Tumor Immmunology Lab and Institute for Computing and Information Sciences, Radboud University Nijmegen), though many folks have contributed to the source code development. If you end up using Dagitty in your research, be sure to cite approriately!
We can view a simple dag on the dagitty website by naivating here:
…and you can edit it using the following shortkeys by holding your cursor over the node of interest and pressing:
| Key | Usage |
|---|---|
| D | Deletes node |
| R | Renames node |
| A | Changes node to being adjusted/unadjusted |
| N | Makes new node |
| U | Changes a node to be unobserved/observed |
You can see a legend of the different node and path colors on the lower lefthand side, as so:
Let’s try it out!
Often times in causal literature (for point-treatment effects), variables will be denoted as follows:
Copy the code in the “model code” section on the righthand side into you R console, if you have access to R. You will need to run install.packages("dagitty") if you don’t have the package already. You will also need to enclose the dag code in quotes and in the dagitty function, as seen below:
#install.packages("dagitty")
library(dagitty)
dag <- dagitty(
'dag {
A [exposure,pos="-1.243,0.333"]
W1 [pos="-1.031,-0.585"]
W2 [pos="-0.140,-0.632"]
W3 [pos="-0.550,0.629"]
Y [outcome,pos="0.160,0.328"]
A -> W3
A -> Y
W1 -> A
W1 -> Y
W2 -> A
W2 -> Y
W3 -> Y
}'
)
plot(dag)
Now that we have our dag, we can perform a variety of functions on the dag to examine different relationships such as ancestors and descendents.
ancestors( dag, "Y" )
## [1] "Y" "W3" "W2" "W1" "A"
descendants( dag, "A" )
## [1] "A" "Y" "W3"
We can also look at all the paths between variables such as A and Y (the open object shows us whether the paths are open or closed):
paths( dag, "A", "Y")$open
## [1] TRUE TRUE TRUE TRUE
paths( dag, "A", "Y")$paths
## [1] "A -> W3 -> Y" "A -> Y" "A <- W1 -> Y" "A <- W2 -> Y"
paths( dag, "A", "Y", directed=T)$paths
## [1] "A -> W3 -> Y" "A -> Y"
We can examine the conditional independencies in the dag:
impliedConditionalIndependencies(dag)
## W1 _||_ W2
## W1 _||_ W3 | A
## W2 _||_ W3 | A
We can also look at the possible adjustment sets (in our case there is only one, but in other cases there may be more than one):
adjustmentSets(dag)
## { W1, W2 }
If we adjust for these variables, we will no longer have open paths between the exposure and outcome:
adjustedNodes(dag) <- c("W1","W2")
paths( dag, "A", "Y", c("W1","W2") )
## $paths
## [1] "A -> W3 -> Y" "A -> Y" "A <- W1 -> Y" "A <- W2 -> Y"
##
## $open
## [1] TRUE TRUE FALSE FALSE
Ok, that was fun, but why both with this if we can do it all on the dagitty website?
R can be helpful if you want to have replicable code that saves a complex dag, examine conditional independencies, explore different adjustment sets, etc. We won’t go over this today, but there are also ways to test relationships in a dag through simulations in R.
If you don’t want to use R, though, you can save directly to dagitty.net by clicking “publish” under the “model” tab above the dag.
Let’s try a more complex graph now.
set.seed(2342)
rdag <- dagitty(dagitty::randomDAG(10, .5))
rdag
## dag {
## x1
## x10
## x2
## x3
## x4
## x5
## x6
## x7
## x8
## x9
## x1 -> x10
## x1 -> x4
## x1 -> x7
## x1 -> x8
## x1 -> x9
## x2 -> x9
## x3 -> x4
## x3 -> x5
## x4 -> x10
## x4 -> x6
## x4 -> x8
## x5 -> x10
## x5 -> x7
## x5 -> x9
## x6 -> x10
## x7 -> x9
## }
exposures(rdag) <-"x1"
outcomes(rdag) <- "x5"
plot(graphLayout(rdag))
If you have RStudio open, run the above code (also accessed on the Github) and try pasting the resulting dag directly into the daggity.net “model code” section on the righthand side. Poof! It renders a dag.
For the R users out there, the ggdag may be useful to you. It is a package that’s built on top of dagitty to extend its functionality to work in the world of tidyverse.
The tidy_dagitty() command creates a tibble with the dag’s details (coordinates, direction of effect, etc.):
tidydag <- tidy_dagitty(dag)
tidydag
## # A DAG with 5 nodes and 7 edges
## #
## # Exposure: A
## # Outcome: Y
## #
## # A tibble: 8 x 8
## name x y direction to xend yend circular
## <chr> <dbl> <dbl> <fct> <chr> <dbl> <dbl> <lgl>
## 1 A -1.24 0.333 -> W3 -0.55 0.629 FALSE
## 2 A -1.24 0.333 -> Y 0.16 0.328 FALSE
## 3 W1 -1.03 -0.585 -> A -1.24 0.333 FALSE
## 4 W1 -1.03 -0.585 -> Y 0.16 0.328 FALSE
## 5 W2 -0.14 -0.632 -> A -1.24 0.333 FALSE
## 6 W2 -0.14 -0.632 -> Y 0.16 0.328 FALSE
## 7 W3 -0.55 0.629 -> Y 0.16 0.328 FALSE
## 8 Y 0.16 0.328 <NA> <NA> NA NA FALSE
For the most part this is nice for visualizing the dag quickly and easily with ggplot:
ggplot(tidydag,aes(x = x, y = y, xend = xend, yend = yend)) +
geom_dag_point() + #this initializes the nodes
geom_dag_edges() + #this initializes the arrows
geom_dag_text() + #this labels the nodes
theme_dag() #this removes the axes from the graph
You can look at paths between exposure and outcome:
ggdag_paths(dag)
Visually examining parents and children of a specific variable:
ggdag_parents(dag, "Y")
Or visualizing the adjustment set needed for your exposure-outcome total effect:
ggdag_adjustment_set(dag)
You can review reference material for more details.
Hopefully this was enough to get you started with dagitty (and ggdag), and that you now:
Johannes Textor, Benito van der Zander, Mark S Gilthorpe, Maciej Liśkiewicz, George TH Ellison, Robust causal inference using directed acyclic graphs: the R package ‘dagitty’, International Journal of Epidemiology, Volume 45, Issue 6, December 2016, Pages 1887–1894, https://doi.org/10.1093/ije/dyw341
http://www.dagitty.net/learn/index.html
http://www.dagitty.net/manual-2.x.pdf
https://cran.r-project.org/web/packages/dagitty/dagitty.pdf
https://cran.r-project.org/web/packages/ggdag/vignettes/intro-to-ggdag.html