0

I have the following code which will return a graph of a DAG:

library(dagitty)
library(ggplot2)

dag <- dagitty( "dag {
  Y <- X <- Z1 <- V -> Z2 -> Y
  Z1 <- W1 <-> W2 -> Z2
  X <- W1 -> Y
  X <- W2 -> Y
  X [exposure]
  Y [outcome]
  }") 

tidy_dag <- tidy_dagitty(dag, layout = "fr")
return_test <- function(tidy_df) {
  
  tidy_df %>%
  ggplot(aes(x = x, y = y, xend = xend, yend = yend)) +
    geom_dag_node() +
    geom_dag_text() +
    geom_dag_edges() +
    theme_dag()
}

return_test(tidy_dag)

I want to return both the dataframe and the graph though. How can I do this? Essentially I want to return the graph as well as tidy_dag. Or maybe just return an object which I can use $ to get a specific element out of it.

user438383
  • 5,716
  • 8
  • 28
  • 43
Eisen
  • 1,697
  • 9
  • 27
  • In general, to return more than one thing from a function in R. you need to return a `list`. For example: `myfun <- function() { ...lots of stuff...; return(list(thing1, thing2)) }` – DanY Oct 25 '21 at 16:56
  • @DanY [No need for `return`](https://stackoverflow.com/a/59090751/1968). – Konrad Rudolph Oct 25 '21 at 16:58

1 Answers1

0

1) attribute This will return the plot but with the dag as an attribute.

return_test2 <- function(tidy_df) {
  
  p <- tidy_df %>%
    ggplot(aes(x = x, y = y, xend = xend, yend = yend)) +
      geom_dag_node() +
      geom_dag_text() +
      geom_dag_edges() +
      theme_dag()
  structure(p, dag = tidy_df$dag)
}

out <- return_test2(tidy_dag)
plot(out)
attr(out, "dag") # dag

A variation of this is to return the dag with the plot as an attribute using this as the structure statement.

structure(tidy_df$dag, plot = p)

2) list Alternately return a list with plot and dag components. That is

return_test3 <- function(tidy_df) {
  
  p <- tidy_df %>%
    ggplot(aes(x = x, y = y, xend = xend, yend = yend)) +
      geom_dag_node() +
      geom_dag_text() +
      geom_dag_edges() +
      theme_dag()
  list(plot = p, dag = tidy_df$dag)
}

out <- return_test3(tidy_dag)
plot(out$plot)
out$dag 
G. Grothendieck
  • 254,981
  • 17
  • 203
  • 341