2016-06-06 78 views
1

我正在研究一个脚本,以在大型网络中可视化社区。我想根据节点的社区成员来选择图中的边,然后更改它们的颜色属性。R igraph:两张图之间的匹配边缘

例如,我可以构造一个图,并给予节点唯一的名字是这样的:

library(igraph) 
library(random) 
g <- barabasi.game(100) 
V(g)$name <- randomStrings(100,len=2,digits=FALSE,loweralpha=FALSE) 
wt <- walktrap.community(g) 

然后选择一个社区进行可视化,并创建一个导出子:

v3 <- V(g)[membership(wt)==3] 
g3 <- induced.subgraph(g,v3) 

的最佳方式我发现得到匹配的边缘是这样的:

matching_edge <- function(g1,e,g2) { 
    # given an edge e in g1, return the corresponding edge in g2 
    name1 <- V(g1)[get.edges(g1,e)[1,1]]$name 
    name2 <- V(g1)[get.edges(g1,e)[1,2]]$name 
    E(g2)[get.edge.ids(g2,c(name1,name2))] 
} 
E(g)$color = 'gray' 
for (e in E(g3)) { 
    eg <- matching_edge(g3,e,g) 
    E(g)[eg]$color <- 'red' 
} 

最后,我的情节:

plot(g,  
    vertex.label=NA, 
    vertex.shape="none", 
    vertex.size=0, 
    edge.arrow.mode=0, 
    edge.width=1) 

这工作不错,但与matching_edge()循环得到痛苦慢了几千个节点的大十岁上下的曲线图。似乎应该有一个更好的方法来做到这一点,但我不知道它是什么。

任何想法?

回答

1

您不需要为此生成子图。

构造图:

library(igraph) 
g <- barabasi.game(100) 
wt <- walktrap.community(g) 

使得颜色数组和基于它们的源节点的社区其分配给边缘:

linkcolors<-rainbow(max(wt$membership)) 
E(g)$color <- linkcolors[membership(wt)[tail_of(g,E(g))]] 

情节:

plot(g,  
    vertex.label=NA, 
    vertex.shape="none", 
    vertex.size=0, 
    edge.arrow.mode=0, 
    edge.width=1) 

这里是一个更长的,一步一步的解决方案版本:

# the largest membership id equals the number of communities 
numberofcommunities<- max(wt$membership) 

# array of as many colours as there are communities 
linkcolors<-rainbow(numberofcommunities) 

# array with the source vertex of each edge 
sourcenodes<-tail_of(g,E(g)) 

# array with community of the source vertex of each edge 
linkmemberships<- membership(wt)[sourcenodes] 

# array with colours corresponding to the 
# community of the source vertex of each edge 
linkcolors <- linkcolors[linkmemberships] 
E(g)$color <- linkcolors 

如果您想要使用目标节点的社区,请使用head_of()而不是tail_of()。

与源和目标节点在同一社区,并以不同方式对待社区之间的边缘(例如,对于无向图)唯一的颜色边缘,绘制前补充一点:

# get edges between communities: 
between_communities_edges<-which(membership(wt)[tail_of(g,E(g))]!=membership(wt)[head_of(g,E(g))]) 
# do something with them: 
E(g)[between_communities_edges]$color='grey95' 
+0

感谢,马吧! head_of()和tail_of()恰恰是我知道*应该*存在的语法,但无法追踪到。如果我将它们结合在一起,那么我就可以准确地再现我对子图的输出,其中只显示了同一集群中两个节点之间的边(这也解决了您用无向图指出的问题)。 – cjolley