Open chadbot opened 3 years ago
If it's any help, morphed graph are lists (in most cases at least), so I tried running the nested morph on the list elements. However this fails when unmorphing because of the way the merge back to the original data is made (multiple/overwritten .tidygraph_node_index / .tidygraph_edge_index aren't handled)
g %>%
morph(to_undirected) %>%
map(~{
.x %>%
morph(to_simple) %>%
activate(nodes) %>%
mutate(community = group_fast_greedy()) %>%
unmorph()
}) %>%
unmorph()
Also tried the following approach in my case – nested morph to subgraph filtering on edges and then on nodes – by making my own morpher. In theory the morpher uses multiple calls to convert, which apply the filters (losing info but that's okay), wrapped in a morph/unmorph which makes sure we don't actually losing info. But the merge back creates duplicates I think because internally the index columns get messed up
to_my_morpher <- function(graph) {
subset <-
graph %>%
activate(nodes) %>%
convert(to_subgraph, [nodes filter]) %>%
activate(edges) %>%
convert(to_subgraph, [edges filter])
list(
subgraph = subset
)
}
my_graph %>%
activate(nodes) %>%
morph(to_my_morpher) %>%
mutate(
group_id = group_components()
) %>%
unmorph()
Get it to work by manually protecting the index columns. Not very pretty.
to_my_morpher <- function(graph) {
subset <-
graph %>%
## protecting the indexes
activate(nodes) %>%
mutate(.tidygraph_node_index_protect = .tidygraph_node_index) %>%
activate(edges) %>%
mutate(.tidygraph_edge_index_protect = .tidygraph_edge_index) %>%
## doing the morph
convert(to_subgraph, [nodes filter], subset_by = "nodes") %>%
convert(to_subgraph, [edges filter], subset_by = "edges") %>%
## putting the indexes back in place
activate(nodes) %>%
mutate(.tidygraph_node_index = .tidygraph_node_index_protect,
.tidygraph_node_index_protect = NULL
) %>%
activate(edges) %>%
mutate(.tidygraph_edge_index = .tidygraph_edge_index_protect,
.tidygraph_edge_index_protect = NULL
)
list(
subgraph = subset
)
}
Not exactly pretty, but you've provided some nice insight into how to think about this. Thanks for taking the time to explain, @gregleleu!
Sure. A more general solution could be added to the package, by merging the two approaches:
On that last point, maybe just not letting subsequent morphs overwrite indexes is enough (and would make sense) but I'm not familiar enough with the internals of the package to know if that 100% works.
One caveat: the initial graph stays as an attribute to subsequent morphs, so it could get very big.
Hello,
I'd like to temporarily convert a directed graph to a simple, undirected graph. I attempted this with the following code:
However, this doesn't seem to work. (The documentation does not indicate that it should work, but it seemed worth a try.)
The code below does the trick by using
convert
twice. But since this is the kind of use casemorph
specifically addresses, it feels more like a workaround than a proper solution.Is there a better way to conduct multiple morphs? And if not, might this be considered in a future update?