dagitty icon indicating copy to clipboard operation
dagitty copied to clipboard

Feature request: add an as.igraph.dagitty method that captures all dagitty node and edge attributes

Open grasshoppermouse opened this issue 2 years ago • 4 comments

This would seamlessly export dagitty objects to igraph, tidygraph, and other powerful graph packages. (BTW, thanks for this great package, which I've integrated into my quantitative methods course)

grasshoppermouse avatar Dec 01 '23 22:12 grasshoppermouse

Can you please help me test this feature? I made it available on a new branch that you can install like this:

remotes::install_github("jtextor/dagitty/r@igraph-export")

jtextor avatar Dec 07 '23 08:12 jtextor

Thanks for tackling this! I get an error when including a beta edge attribute. It would also be nice to capture the exposure and outcome attributes.

library(dagitty)

g <- dagitty('dag{
  A [pos="0,-2"]
  B [pos="2,-2"]
  D [outcome,pos="2,0"]
  E [exposure,pos="0,0"] 
  Z [pos="1,-1"]
  A -> { E Z }
  B -> { D Z }
  E -> D
  Z -> { D E } }'
)
gi <- convert(g, to = 'igraph')
igraph::edge_attr(gi)
#> $arrow.mode
#> [1] "->" "->" "->" "->" "->" "->" "->"
igraph::vertex_attr(gi) # Doesn't capture exposure or outcome
#> $name
#> [1] "A" "B" "D" "E" "Z"
#> 
#> $x
#> [1] 0 2 2 0 1
#> 
#> $y
#> [1] -2 -2  0  0 -1

# Error when including beta attribute
g <- dagitty('dag{z -> x [beta=-.6] x <- y [beta=-.6] }')
gi <- convert(g, to = 'igraph')
#> Error: object 'ee' not found

Created on 2023-12-07 with reprex v2.0.2

grasshoppermouse avatar Dec 08 '23 02:12 grasshoppermouse

Is this conversion meant exclusively for visualization purposes? At the moment, directed, bidirectional and undirected edges are not distinguishable in a way that is useful for computation.

Note that igraph does not support mixed graphs, nor is it likely to do so in the foreseeable future. There are ways around this, but the best way depends on what one might want to do with this graph in igraph (other than just plot it).

What are the goals here?

  • Just transfer to igraph and plot?
  • Transfer to igraph and transfer back (roundtripping), with minimal loss of information? A relevant question here is whether in dagitty <-> is treated as a pair of edges (with potentially distinct attributes) or a single edge of a special type?
  • Compute with the graph in igraph? If so, compute what?

Probably the most flexible representation for computation is not a single graph, but a pair of graphs, one directed and one undirected. These two can then be combined using union(..., byname=FALSE) after an application-appropriate transformation of the udirected one to directed.

szhorvat avatar Dec 08 '23 02:12 szhorvat

As far as I am concerned, this is currently for visualization purposes mainly, and will only support a subset of the types of mixed graphs that dagitty supports. Current supported edge types are: "-", "->", "<->", "@--", "@->", "@-@"; but most of the applications only need "-", "->", "<->". In dagitty <-> is not the same thing as two separate directed edges.

Because only undirected, directed, and bi-directed edges cover most use cases, I was thinking of supporting this using the arrow.mode attribute (https://igraph.org/r/doc/plot.common.html currently says "this parameter can be used as a ‘cheap’ solution for drawing “mixed” graphs"). This makes it possible to export a graph and plot it in igraph relatively easily e.g. this currently works:

igraph::plot.igraph(dagitty::convert(dagitty::getExample("Shrier"),"igraph"))

I don't think downstream computations in igraph are currently useful or required, but if someone would do this (e.g. manipulate the graph), it would be quite easy to convert this back to dagitty, provided that the arrow.mode attribute is preserved.

Best regards Johannes

jtextor avatar Dec 08 '23 08:12 jtextor