2016-06-06 108 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