# Create tranpose (edge reversed) of graph?

**URL:** <https://igraph.discourse.group/t/create-tranpose-edge-reversed-of-graph/1219>\
**Category:** Usage\
**Tags:** Python\
**Created:** [10 May 2022 23:30 UTC](https://igraph.discourse.group/t/create-tranpose-edge-reversed-of-graph/1219 "2022-05-10T23:30:49Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![salterduke](https://avatars.discourse-cdn.com/v4/letter/s/eb9ed0/32.png) [@salterduke](https://igraph.discourse.group/u/salterduke)\
**Post date:** [10 May 2022 23:30 UTC](https://igraph.discourse.group/t/create-tranpose-edge-reversed-of-graph/1219/1 "2022-05-10T23:30:49Z")

</div>

Hi, I’m using python igraph to write an algorithm (exact algorithm not relevant), and part of it calls for reversing the direction of all edges in a directed graph.

I can’t see a simple way to do this. I would guess that it’s not an uncommon thing people might want to do, so perhaps there is a simple way of doing it which I have just missed. I’ve searched the documentation and the forum for “transpose”, “reverse edges” and just “reverse”, but nothing seems relevant.

At the moment, I’m getting the weighted adjacency matrix, transposing it, and creating a new graph from said transpose, and copying over all the vertex attributes. Since weight is the only edge attribute I’m dealing with, this works fine, but I suspect there’s a more efficient and neater way of doing it.

Does anyone know if there’s a simple built-in function for doing it, or alternatively a more efficient way of doing it without a self-contained function?

Cheers  
Michal

---

<div class="post-metadata">

**Author:** ![szhorvat](https://yyz2.discourse-cdn.com/free1/user_avatar/igraph.discourse.group/szhorvat/32/3_2.png) [@szhorvat](https://igraph.discourse.group/u/szhorvat)\
**Post date:** [11 May 2022 05:03 UTC](https://igraph.discourse.group/t/create-tranpose-edge-reversed-of-graph/1219/2 "2022-05-11T05:03:34Z")

</div>

> [@salterduke](#):
>
> Does anyone know if there’s a simple built-in function for doing it

At the moment, no.

The reason is that (almost?) any operation that takes edge directions into account has a `mode` parameter that can be set to either `OUT` or `IN`, with `IN` indicating that the graph should be interpreted in the reverse direction.

If you feel that you still need this feature, please do comment on [this feature request](https://github.com/igraph/igraph/issues/1477) and explain why using the `mode` parameter is insufficient or inconvenient for you. Input from users will be helpful in arriving to a decision about whether (and how) to implement this.

---

<div class="post-metadata">

**Author:** ![vtraag](https://yyz2.discourse-cdn.com/free1/user_avatar/igraph.discourse.group/vtraag/32/38_2.png) [@vtraag](https://igraph.discourse.group/u/vtraag)\
**Post date:** [23 May 2022 08:05 UTC](https://igraph.discourse.group/t/create-tranpose-edge-reversed-of-graph/1219/3 "2022-05-23T08:05:43Z")

</div>

> [@salterduke](#):
>
> alternatively a more efficient way of doing it without a self-contained function?

Using the adjacency matrix uses a full matrix representation, unless you specifically use `get​_adjacency​_sparse`. Using the sparse representation will obviously be more efficient. Alternatively, you could also use the edge list directly, as follows

```Python
el = G.get_edgelist()
el_t = (tuple(reversed(e)) for e in el)
G_t = ig.Graph(el_t, directed=True) 

```

---

<div class="post-metadata">

**Author:** ![szhorvat](https://yyz2.discourse-cdn.com/free1/user_avatar/igraph.discourse.group/szhorvat/32/3_2.png) [@szhorvat](https://igraph.discourse.group/u/szhorvat)\
**Post date:** [23 May 2022 08:54 UTC](https://igraph.discourse.group/t/create-tranpose-edge-reversed-of-graph/1219/4 "2022-05-23T08:54:53Z")

</div>

These methods do not preserve the attributes though. I think there is great value in introducing an efficient function that reverses edge directions.

---

<div class="post-metadata">

**Author:** ![vtraag](https://yyz2.discourse-cdn.com/free1/user_avatar/igraph.discourse.group/vtraag/32/38_2.png) [@vtraag](https://igraph.discourse.group/u/vtraag)\
**Post date:** [23 May 2022 09:32 UTC](https://igraph.discourse.group/t/create-tranpose-edge-reversed-of-graph/1219/5 "2022-05-23T09:32:12Z")

</div>

You are constructing a completely new graph in this way. So, there simply aren’t attributes (yet). But, the edge order is identical, so you can easily copy them over: e.g `G_t.es['weight'] = G.es['weight']`.

Regardless, it would be convenient if this was directly implemented.

---

<div class="post-metadata">

**Author:** ![KeesP](https://avatars.discourse-cdn.com/v4/letter/k/2bfe46/32.png) [@KeesP](https://igraph.discourse.group/u/KeesP)\
**Post date:** [29 June 2022 15:32 UTC](https://igraph.discourse.group/t/create-tranpose-edge-reversed-of-graph/1219/6 "2022-06-29T15:32:09Z")

</div>

> But, the edge order is identical, so you can easily copy them over.

Not necessarily if the graph contains isolates as I found out (see [Crash in rigraph function permute() · Issue #542 · igraph/rigraph · GitHub](https://github.com/igraph/rigraph/issues/542) )

The following code seems to work in R:

```auto
# transpose directed graph, including isolates
# keep edge attributes
t.graph <- function(g){
tg <- add_edges(delete_edges(g, edges=E(g)) # delete edges from original graph and
     , t(get.edgelist(g, names=FALSE)[,2:1])) # revert edges and transpose edgelist
edge_attr(tg) <- edge_attr(g) # save edge attributes
return(tg)
}

```

---

<div class="post-metadata">

**Author:** ![KeesP](https://avatars.discourse-cdn.com/v4/letter/k/2bfe46/32.png) [@KeesP](https://igraph.discourse.group/u/KeesP)\
**Post date:** [2 July 2022 13:43 UTC](https://igraph.discourse.group/t/create-tranpose-edge-reversed-of-graph/1219/7 "2022-07-02T13:43:42Z")

</div>

Transpose graph in Magritte style.

```auto
library(igraph)
# magritte style
# transpose directed graph, keep isolates and edge attributes
t.graph <- function(g){
  g %>% delete_edges(E(.)) %>%
  add_edges(g %>% get.edgelist(names=FALSE) %>% .[,2:1] %>% t ) -> tg
  edge_attr(g) -> edge_attr(tg) 
  tg %>% return
}

# check if double transpose is an identical function
g <- make_graph(c(1,2,4,5)) + 1
gtt <- t.graph(t.graph(g))
isomorphic(g, gtt)
identical_graphs(g, gtt)

```

---

<div class="post-metadata">

**Author:** ![KeesP](https://avatars.discourse-cdn.com/v4/letter/k/2bfe46/32.png) [@KeesP](https://igraph.discourse.group/u/KeesP)\
**Post date:** [9 July 2022 11:39 UTC](https://igraph.discourse.group/t/create-tranpose-edge-reversed-of-graph/1219/8 "2022-07-09T11:39:38Z")

</div>

Note that unlike graph\_from\_edgelist, add\_edges needs a transposed edgelist. Not very relevant for Python.

---

<div class="post-metadata">

**Author:** ![szhorvat](https://yyz2.discourse-cdn.com/free1/user_avatar/igraph.discourse.group/szhorvat/32/3_2.png) [@szhorvat](https://igraph.discourse.group/u/szhorvat)\
**Post date:** [9 July 2022 13:28 UTC](https://igraph.discourse.group/t/create-tranpose-edge-reversed-of-graph/1219/9 "2022-07-09T13:28:35Z")

</div>

R/igraph 1.3.3 will include the `reverse_edges()` function when it’s released:

```r
> g <- make_graph(~ a-+b, b+-c)
> g
IGRAPH 2472e57 DN-- 3 2 -- 
+ attr: name (v/c)
+ edges from 2472e57 (vertex names):
[1] a->b c->b
> reverse_edges(g)
IGRAPH 523cafd DN-- 3 2 -- 
+ attr: name (v/c)
+ edges from 523cafd (vertex names):
[1] b->a b->c
> reverse_edges(g, 1) # reverse only the 1st edge
IGRAPH d41e8b1 DN-- 3 2 -- 
+ attr: name (v/c)
+ edges from d41e8b1 (vertex names):
[1] b->a c->b

```

So will python-igraph 0.9.12.
