在igraph(R包)中转置有向图的边缘(反转图形)。

3
假设我在R中有一个igraph图,并且想要反转所有边:

Transpose_graph

看见 转置图

library(igraph)
library(tidyverse)
g <- make_star(n=6)
plot(g)
gt <- transposeGraph(g) # hypothetical function
plot(gt)

一种方法似乎是重建图形,但我担心性能和顶点属性的丢失:

gt <- graph_from_data_frame(as_data_frame(g) %>% select(to, from))

还有其他的想法吗?

4个回答

2
可能的答案可以在这里找到,但它没有保留顶点属性。
使用get.vertex.attributeset.vertex.attribute应该可以恢复属性。
尝试:
library(igraph)
library(tidyverse)

g <- make_star(n=6)
plot(g)

transposeGraph <- function(g) {
  g %>% get.edgelist %>%
    {cbind(.[, 2], .[, 1])} %>%
    graph.edgelist
}

gt <- transposeGraph(g)
plot(gt)

此示例是由 reprex包 (v0.3.0) 创建于2020年9月10日。

性能比较表明,在具有100个顶点的星形图上,速度大约快了10倍:

Unit: microseconds
                                                         expr      min        lq     mean   median
 graph_from_data_frame(as_data_frame(g) %>% select(to, from)) 4300.308 4495.1795 4844.328 4654.769
                                            transposeGraph(g)  315.487  350.5645  457.711  404.308
       uq       max neval cld
 4806.770 13324.719   100   b
  437.539  4488.205   100  a 


你能解释一下,为什么你认为这样会有更好的性能表现吗? - c0bra
我不确定这是否具有更好的性能,但它似乎难以变得更简单。最好的方式是创建一个更大的随机图,并使用microbenchmark::microbenchmark(transposeGraph_dataframe_solution(g), transposeGraph_igraph_solution(g))测试两种解决方案。 - Waldi
一个相关的答案:https://dev59.com/CLzpa4cB1Zd3GeqPHkQ9#63016581 - Waldi
@c0bra,你有机会对你的数据集进行性能比较吗? - Waldi

1

使用R/igraph 1.3.3或更高版本,您可以使用reverse_edges()函数。该函数保留所有属性,并允许仅翻转某些边缘。

翻转所有边缘的别名是t()(用于“转置”)。


0
这里讨论的解决方案在图形包含孤立点时将失败。
library(igraph)
tGraph <- function(g)
          { g %>% get.edgelist %>% {cbind(.[, 2], .[, 1])} %>% graph.edgelist}
g <- make_graph(c(1,2,4,5)) + 1
gt <- tGraph(g)
gtt <- tGraph(gt)

isomorphic(g, gtt)
[1] FALSE
identical_graphs(g, gtt)
[1] FALSE

以下代码保留了隔离符和图形属性。
t.graph <- function(g){
tg <- add_edges(delete_edges(g, edges=E(g))
     , t(get.edgelist(g, names=FALSE)[,2:1])) # revert edges
edge_attr(tg) <- edge_attr(g)                 # save edge attributes                                               
return(tg)
}

g <- make_graph(c(1,2,4,5)) + 1
gtt <- t.graph(t.graph(g))

isomorphic(g, gtt)
[1] TRUE
identical_graphs(g, gtt)
[1] TRUE

请注意,与graph_from_edgelist不同,add_edges需要一个转置的边列表作为顶点序列。

-2

我目前正在运行以下代码,因为它保留了所有节点和边缘属性。


library(igraph)
#> 
#> Attache Paket: 'igraph'
#> The following objects are masked from 'package:stats':
#> 
#>     decompose, spectrum
#> The following object is masked from 'package:base':
#> 
#>     union

g <- make_star(n=6)
V(g)$name <- LETTERS[1:6]
E(g)$weight <- 1:5
plot(g)


transposeGraph <- function(g){
  gDf <- as_data_frame(g, what = "both")
  graph_from_data_frame(gDf$edges[,c(2:1, 3:ncol(gDf$edges))], directed = T, gDf$vertices)
}

gt <- transposeGraph(g)

plot(gt)

2020年09月28日由reprex package (v0.3.0)创建


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接