Reputation: 3852
I have a non-directed network in R which when plotted in igraph looks something like:
plot(g2)
From this main graph, I extract all clusters / sub-graphs with minimum vertices = 4:
modules <- decompose.graph(g2, min.vertices = 4)
out <- modules[order(sapply(modules, ecount), decreasing=T)]
Giving:
> head(modules)
[[1]]
IGRAPH UN-- 4 4 --
+ attr: name (v/c), value (e/n), sourceID (e/n), targetID (e/n)
+ edges (vertex names):
[1] 333--342 333--324 333--323 342--324
[[2]]
IGRAPH UN-- 4 4 --
+ attr: name (v/c), value (e/n), sourceID (e/n), targetID (e/n)
+ edges (vertex names):
[1] 27--25 27--20 25--20 25--21
[[3]]
IGRAPH UN-- 4 3 --
+ attr: name (v/c), value (e/n), sourceID (e/n), targetID (e/n)
+ edges (vertex names):
[1] 662--657 662--705 706--657
[[4]]
IGRAPH UN-- 4 3 --
+ attr: name (v/c), value (e/n), sourceID (e/n), targetID (e/n)
+ edges (vertex names):
[1] 793--792 793--795 793--794
[[5]]
IGRAPH UN-- 4 3 --
+ attr: name (v/c), value (e/n), sourceID (e/n), targetID (e/n)
+ edges (vertex names):
[1] 746--747 746--722 746--721
[[6]]
IGRAPH UN-- 4 3 --
+ attr: name (v/c), value (e/n), sourceID (e/n), targetID (e/n)
+ edges (vertex names):
[1] 285--284 285--286 287--284
I can plot these as one graph by doing:
vertexes <- character()
data_frames <- list()
for(i in 1:length(out)) {
vertexes[i] <- list(vertex.attributes(out[[i]])$name)
data_frames[[i]] <- get.data.frame(out[[i]])
}
sub_nodes = unlist(vertexes)
subv <- sub_nodes
g3 <- induced.subgraph(graph=g2,vids=subv)
plot(g3)
I can calculate the betweenness of this main graph and display the outcome:
wc <- edge.betweenness.community(g3, weights = NULL
,directed = FALSE,bridges = TRUE)
plot(wc, g3)
This splits up each sub cluster as a community.
What I want is the betweenness evaluated for each individual sub cluster:
I calculate the betweenness of each subgraph by doing:
betweenness_sub <- list()
for(i in 1:length(out)) {
btws <- edge.betweenness.community(out[[i]], weights = NULL
,directed = FALSE,bridges = TRUE)
print(btws)
betweenness_sub[[i]] <- btws
}
This gives:
> head(betweenness_sub)
[[1]]
IGRAPH clustering edge betweenness, groups: 2, mod: 0.17
+ groups:
$`1`
[1] "646" "647" "723"
$`2`
[1] "713" "714" "710"
[[2]]
IGRAPH clustering edge betweenness, groups: 1, mod: 0
+ groups:
$`1`
[1] "685" "684" "686" "691" "690"
[[3]]
IGRAPH clustering edge betweenness, groups: 1, mod: 0
+ groups:
$`1`
[1] "719" "718" "734" "753" "715"
[[4]]
IGRAPH clustering edge betweenness, groups: 1, mod: 0
+ groups:
$`1`
[1] "702" "757" "720" "735"
[[5]]
IGRAPH clustering edge betweenness, groups: 1, mod: 0
+ groups:
$`1`
[1] "83" "80" "88" "87" "81"
[[6]]
IGRAPH clustering edge betweenness, groups: 1, mod: 0
+ groups:
$`1`
[1] "333" "342" "324" "323"
I can plot these individually by doing:
plot(betweenness_sub[[1]], out[[1]])
What I want to do now is plot the communities of each of these sub clusters but altogether like in the third plot.
This time the highlighted communities will be those as described in the above lists..
Is there any way to "regroup" "combine" or mesh these individual sub graph communities to a full graph?
As a further example, if we take minimum vertices = 7, and run the above code we get:
vertexes <- character()
data_frames <- list()
for(i in 1:length(out)) {
vertexes[i] <- list(vertex.attributes(out[[i]])$name)
data_frames[[i]] <- get.data.frame(out[[i]])
}
sub_nodes = unlist(vertexes)
subv <- sub_nodes
g3 <- induced.subgraph(graph=gg,vids=subv)
plot(g3)
wc <- edge.betweenness.community(g3, weights = E(out)$value
,directed = FALSE,bridges = TRUE)
# g3 <- delete.edges(g3, wc$removed.edges[seq(length=1)])
plot(wc, g3)
Whereas, if we consider the biggest cluster individually, we get:
plot(betweenness_sub[[1]], out[[1]])
I want the communities calculated on individual clusters in the second image, in the same arrangements as in the first image. Any ideas?
Edit 3. The data used to create the plots (min vertices=7) above is as follows:
> get.data.frame(g3)
from to value sourceID targetID
1 74 80 0.2829 255609 262854
2 74 61 0.2880 255609 179585
3 80 1085 0.2997 262854 3055482
4 476 502 0.2714 1442372 1475074
5 476 524 0.2963 1442372 1532560
6 476 479 0.2214 1442372 1448436
7 476 497 0.2714 1442372 1466635
8 476 498 0.2714 1442372 1467171
9 476 500 0.2714 1442372 1468099
10 502 479 0.2714 1475074 1448436
11 502 497 0.1215 1475074 1466635
12 502 498 0.1215 1475074 1467171
13 502 500 0.1215 1475074 1468099
14 524 479 0.2963 1532560 1448436
15 1045 1046 0.1842 2970629 2971615
16 1046 1085 0.2963 2971615 3055482
17 1046 1154 0.2714 2971615 3087803
18 1047 1120 0.2886 2972434 3076314
19 1085 1154 0.2577 3055482 3087803
20 1085 1187 0.2850 3055482 3101131
21 1085 1209 0.2850 3055482 3110186
22 1097 1159 0.2922 3062163 3090708
23 1097 1087 0.2256 3062163 3058341
24 1097 1158 0.2922 3062163 3090707
25 1097 1160 0.2922 3062163 3090709
26 1097 1177 0.2577 3062163 3099199
27 1098 1159 0.2922 3062164 3090708
28 1098 1087 0.2256 3062164 3058341
29 1098 1158 0.2922 3062164 3090707
30 1098 1160 0.2922 3062164 3090709
31 1098 1177 0.2577 3062164 3099199
32 1118 1119 0.1587 3076246 3076248
33 1118 1090 0.2256 3076246 3058962
34 1119 1120 0.1736 3076248 3076314
35 1119 1144 0.2035 3076248 3085240
36 1119 1145 0.2035 3076248 3085241
37 1154 1243 0.2577 3087803 3130848
38 1154 1187 0.2305 3087803 3101131
39 1154 1209 0.2305 3087803 3110186
40 1154 1244 0.2577 3087803 3131379
41 1159 1087 0.2922 3090708 3058341
42 1243 1187 0.1488 3130848 3101131
43 1243 1209 0.1488 3130848 3110186
44 1243 1244 0.1215 3130848 3131379
45 1243 1281 0.2997 3130848 3255811
> g <- graph.data.frame(get.data.frame(g3), directed=FALSE)
> gg
IGRAPH UN-- 33 45 --
+ attr: name (v/c), value (e/n), sourceID (e/n), targetID (e/n)
+ edges (vertex names):
[1] 74 --80 74 --61 80 --1085 476 --502 476 --524 476 --479 476 --497 476 --498 476 --500 502 --479 502 --497 502 --498
[13] 502 --500 524 --479 1045--1046 1046--1085 1046--1154 1047--1120 1085--1154 1085--1187 1085--1209 1097--1159 1097--1087 1097--1158
[25] 1097--1160 1097--1177 1098--1159 1098--1087 1098--1158 1098--1160 1098--1177 1118--1119 1118--1090 1119--1120 1119--1144 1119--1145
[37] 1154--1243 1154--1187 1154--1209 1154--1244 1159--1087 1243--1187 1243--1209 1243--1244 1243--1281
Edit 2:
It is possible to plot multiple clusters using the plotly
package:
par(mfrow=c(2,3))
par(mar = rep(2, 2))
for(i in 1:length(out)) {
plot(betweenness_sub[[i]], out[[i]])
}
But I want to know how to do this specifically using igraph in order to maintain the circular structure as in the figures described.
Upvotes: 2
Views: 1894
Reputation: 2922
Below is my algorithm, it is not very elegant, but it seems to work. The basic idea is to get the group information from your betweenness_sub
and concatenate them into a big list, for example, subs
, and use plot(g3, mark.groups = subs)
to plot the whole graph with the group information from subs
, i.e. betweenness-sub
. Note that in my code, graph
is the graph data.frame
as your posted.
g2 <- graph.data.frame(graph, directed=FALSE)
modules <- decompose.graph(g2, min.vertices = 7)
out <- modules[order(sapply(modules, ecount), decreasing=T)]
vertexes <- character()
data_frames <- list()
for(i in 1:length(out)) {
vertexes[i] <- list(vertex.attributes(out[[i]])$name)
data_frames[[i]] <- get.data.frame(out[[i]])
}
sub_nodes = unlist(vertexes)
subv <- sub_nodes
g3 <- induced.subgraph(graph=g2,vids=subv)
plot(g3)
wc <- edge.betweenness.community(g3, weights = NULL
,directed = FALSE,bridges = TRUE)
plot(wc, g3)
betweenness_sub <- list()
for(i in 1:length(out)) {
btws <- edge.betweenness.community(out[[i]], weights = NULL
,directed = FALSE,bridges = TRUE)
print(btws)
betweenness_sub[[i]] <- btws
}
subs <- list()
k <- 1
for (sub in betweenness_sub) {
for (i in 1:length(sub)) {
subs[[k]] <- sub[[i]]
k = k + 1
}
}
plot(g3, mark.groups = subs)
Upvotes: 3