Software to Draw DAGs

Amy Pitts and Charly Fowler

2023-02-14

Outline

Softwares:

Presentation Structure:

We will conclude with a comparison chart, honorable mentions, and our general recommendations depending on your needs.

Tikz

This is a LaTeX package for creating DAGs.

\usepackage{tikz}
\tikzset{> = stealth} % nicer looking arrows

Overview:

Resources:

Tikz

Pros:

Cons:

Tikz

Code

\begin{center}
\begin{tikzpicture}
% nodes
%generally: create node, circle shape, 
%named C with (X = 0, Y = 2) coordinates, 
%labeled C
\node[circle, draw] (C) at (0, 2) {C}; 
\node[circle, draw]  (A) at (1, 0) {A};
\node[circle, draw]  (Y) at (3, 0) {Y};
% edges
\draw[->, thick]
(C) edge (A)
(C) edge (Y)
(A) edge (Y);

\end{tikzpicture}
\end{center}

DAG 1

Tikz

Code

\begin{center}
\begin{tikzpicture}
% nodes
\node[circle, draw] (C) at (0, 0)  {C};
\node[circle, draw]  (A) at (1.5, 0) {A};
\node[circle, draw]  (Y) at (4.5, 0) {Y};
\node[circle, draw] (M) at (3, 0) {M}; 
% edges
\draw[->, thick]
(C) edge (A)
(C) edge [bend right=40] (Y) % creating curve 
(C) edge [bend right=30] (M)
(A) edge [bend left=30] (Y)
(A) edge (M)
(M) edge (Y);

\end{tikzpicture}
\end{center}

DAG 2

Tikz

Code

\begin{center}
\begin{tikzpicture}
% nodes
% note we can use math mode to write labels!
\node[circle, draw] (C1) at (0, 2)  {$C_1$}; 
\node[circle, draw] (C2) at (0, 0)  {$C_2$}; 
\node[circle, draw] (C3) at (2, 2)  {$C_3$}; 
\node[circle, draw]  (A) at (0, 4) {$A$};
\node[circle, draw]  (Y) at (4, 4) {$Y$};
\node[circle, draw] (M) at (2, 4) {$M$}; 
% edges
\draw[->, thick]
(C1) edge (A)
(C1) edge (M)
(C1) edge (Y)
(C1) edge (C2)
(C2) edge [bend left=40] (A)  
(C2) edge (M) 
(C2) edge [bend right=30] (Y)
(C3) edge (M) 
(C3) edge (Y) 
(A) edge [bend left=30] (Y)
(A) edge (M)
(M) edge (Y);

\end{tikzpicture}
\end{center}

DAG 3

DAGitty

This is a browser-based environment for creating, editing and analyzing DAGs. It also an available R package on CRAN.

library(dagitty)

Overview:

Resources:

DAGitty

Pros:

Cons:

DAGitty

Code

dag1 <- dagitty( "dag {
                  A [exposure]
                  Y [outcome]
                  A -> Y
                  C -> A 
                  C -> Y}" )
coordinates(dag1 ) <-  list(
  x = c(C = 0, A = 0, Y = 1),
  y = c(C = 0, A = 1, Y = 1)
)

plot(dag1)

DAG 1

DAGitty

Code

dag2 <- dagitty( 'dag {
  bb="-1.956,-1.956,1.956,1.956"
  A [exposure,pos="-1.000,0.000"]
  C [pos="-1.500,0.000"]
  M [pos="-0.500,0.000"]
  Y [outcome,pos="0.000,0.000"]
  A -> M
  A -> Y [pos="-0.500,-0.250"]
  C -> A
  C -> M [pos="-1.00,0.250"]
  C -> Y [pos="-1.00,0.500"]
  M -> Y}' )

plot(dag2)

DAG 2

DAGitty

Code

dag3 <- dagitty('dag {
  bb="-3,-3,3,3"
  A [exposure,pos="0.250,0.150"]
  C_3 [pos="1.025,0.600"]
  C_2 [pos="0.500,1.000"]
  C_1 [pos="0.500,0.600"]
  M [pos="0.900,0.150"]
  Y [outcome,pos="1.500,0.150"]
  A -> M
  A -> Y [pos="1.000,0.090"]
  C_1 -> C_2
  C_3 -> M
  C_3 -> Y
  C_2 -> A [pos="0.150,0.500"]
  C_2 -> M
  C_2 -> Y [pos="1.500,0.800"]
  C_1 -> A
  C_1 -> M
  C_1 -> Y
  M -> Y
}')

plot(dag3)

DAG 3

ggdag

This is an R package on CRAN that is built on top of dagitty and used ggplot2 and ggplot to

library(ggdag)

Overview:

Resources:

Vignettes/Tutorials:

ggdag

Pros:

Cons:

ggdag

Code

dag1 <- 
  dagify(
    # relationship for each node
    A ~ C,
    Y ~ A + C,
    exposure = "A",
    outcome = "Y",
    # location for each node
    coords = list(
      x = c(Y = 4, A = 2, C = 2),
      y = c(Y = 2, A = 2, C = 3)
    )
  )

# could use ggdag or ggplot
ggdag(dag1, layout = "circle", 
      node_size = 20) +
  theme_void() +
  labs(title = "DAG1")

DAG 1

ggdag

Code

dag2 <- 
  dagify(
    # relationship for each node
    A ~ C,
    M ~ A + C,
    Y ~ M + A + C,
    exposure = "A",
    outcome = "Y" ,
    coords = list(
      x = c(Y = 5, M = 4, A = 3, C = 2),
      y = c(Y = 2, M = 2, A = 2, C = 2)
    )
  )

# plotting with curves 
dag2 %>% 
  ggplot(aes(x = x, y = y, 
             xend = xend, yend = yend)) +
  geom_dag_point() +
  geom_dag_edges_arc(
    curvature = c(0, 0.1, 0,-0.25,-0.25,0)
  )+
  geom_dag_text() +
  theme_dag() + 
  labs(title = "DAG2")

DAG 2

ggdag

Code

dag3 <- 
  dagify(
    # relationship for each node
    A ~ C_1 + C_2,
    C_2 ~ C_1,
    M ~ A + C_1 + C_2 + C_3,
    Y ~ M + A + C_1 + C_2 + C_3,
    exposure = "A",
    outcome = "Y"
  )

ggdag(dag3, layout = "circle") +
  theme_void() +
  labs(title = "DAG3")

DAG 3

ggdag

Code

dag3 <- dagify(
   # relationship for each node
    A ~ C1 + C2,
    C2 ~ C1,
    M ~ A + C1 + C2 + C3,
    Y ~ M + A + C1 + C2 + C3,
    # specify exposure and outcome 
    exposure = "A",
    outcome = "Y",
    # Location of each node
    coords = list(
      x = c(Y = 3, M = 2, A = 1, 
            C1 = 1, C2 = 1, C3 = 2),
      y = c(Y = 2, M = 2, A = 2,
            C1 = 1, C2 = 0, C3 = 1)
    )
  ) 

dag3 %>% 
  ggplot(aes(x = x, y = y, 
             xend = xend, 
             yend = yend)) +
  geom_dag_point() + # plot nodes
  #geom_dag_edges() + # straight edges 
  geom_dag_edges_arc( 
    curvature = c(0, 0.25, 0, 0, 
                  0, 0, 0.25, 0, 
                  -0.25, 0, 0, 0)
    # straight + curved edges
  ) +
  theme_void() +
  geom_dag_text(
    parse = TRUE, 
    label = c( # include subscripts
      "A", expression(C[1]), 
       expression(C[2]), 
       expression(C[3]), "M", "Y")
  ) +
  labs(title = "DAG3")

DAG 3

dagR

This is an R package for drawing, manipulating and evaluating DAGs, and simulating corresponding data.

library(dagR)

Overview:

Resources:

dagR

Pros:

Cons:

dagR

Code

dag.dat <-
    dag.init(outcome = NULL, exposure = NULL,
             covs = c(1), #1 per covariate
             arcs = # 0:exposure, -1: outcome # write in pairs
               c(1,0, # C to A
                 1,-1, # C to Y
                 0,-1), # A to Y
             assocs = c(0), # directed arcs, one 0 per cov
             xgap = 0.04, 
             ygap = 0.05, 
             len = 0.1,
             x.name = "Exposure",
             cov.names = c("Covariate"),
             y.name = "Outcome",
             symbols = c("A", "C", "Y"),
             noxy = T
             )

dag.dat$x <- c(0.25, 0, 1) # A, C, Y x-axis positions
dag.dat$y <- c(0, 1, 0)


plot1 <- dag.draw(dag.dat, noxy = T, legend = T)

DAG 1

dagR

Code

dag.dat <-
    dag.init(outcome = NULL, exposure = NULL,
             covs = c(1, 1), #1 per covariate
             arcs = # 0:exposure, -1: outcome # write in pairs
               c(1,0, # C to A
                 1,2, # C to M
                 1,-1, # C to Y
                 0, 2, # A to M
                 0,-1, # A to Y
                 2,-1 # M to Y
             ),
             assocs = c(0, 0), # directed arcs, one 0 per cov
             xgap = 0.04, 
             ygap = 0.05, 
             len = 0.1,
             symbols = c("A", "C", "M", "Y"),
             noxy = T
             )

dag.dat$x <- c(0.33, 0, 0.66, 1) # A, C, M, Y x-axis positions

plot2 <- dag.draw(dag.dat, noxy = T, legend = F)

DAG 2

dagR

Code

dag.dat <-
    dag.init(outcome = NULL, exposure = NULL,
             covs = c(1, 1, 1, 1), #1 per covariate
             arcs = # 0:exposure, -1: outcome # write in pairs
               c(1,0, # C1 to A
                 1,4, # C1 to M
                 1,-1, # C1 to Y
                 1,2, # C1 to C2
                 2,0, # C2 to A
                 2,4, # C2 to M
                 2,-1, # C2 to Y
                 3,4, # C3 to M
                 3,-1, # C3 to Y
                 4,-1, # M to Y
                 0, 4, # A to M
                 0,-1 # A to Y
                 
             ),
             assocs = c(0, 0, 0, 0), # directed arcs, one 0 per cov
             xgap = 0.04, 
             ygap = 0.05, 
             len = 0.05,
             symbols = c("A", "W", "X", "Z","M", "Y"),
             noxy = T
             )

plot3 <- dag.draw(dag.dat, noxy = T, legend = F)

DAG 2

Comparison

Honorable Mentions

Quiver: Web resource to quickly draw a DAG by clicking and dragging, provides LaTeX code

 

CausalFusion: Web resource that can generate DAGs and has analysis capabilities, requires an approved account

 

Tetrad: Free Downloadable tool (with a 30 year history) that creates, simulates data from, estimates, tests and predicts with causal and statistical models.

 

shinyDAG: Web app that use R and LaTeX to create publication-quality images of DAGs.

 

igraph: R Package designed to handle large graphs

Conclusion