R:igraph,社区检测,边缘。中间值方法,统计/列出每个社区的成员?
我有一个相对较大的图,有真实世界事务的顶点:524条边:1125。边是定向的,并具有权重(包含是可选的)。 我试图调查图中的各种社区,基本上需要一种方法: -计算所有可能的社区 -计算最佳社区数 -返回每个(最佳)社区成员的成员/# 到目前为止,我已经成功地收集了以下代码,这些代码绘制了一个对应于各种社区的彩色编码图,但是我不知道如何控制社区的数量(即绘制拥有最高成员资格的前5个社区)或列出特定社区的成员R:igraph,社区检测,边缘。中间值方法,统计/列出每个社区的成员?,r,igraph,modularity,R,Igraph,Modularity,我有一个相对较大的图,有真实世界事务的顶点:524条边:1125。边是定向的,并具有权重(包含是可选的)。 我试图调查图中的各种社区,基本上需要一种方法: -计算所有可能的社区 -计算最佳社区数 -返回每个(最佳)社区成员的成员/# 到目前为止,我已经成功地收集了以下代码,这些代码绘制了一个对应于各种社区的彩色编码图,但是我不知道如何控制社区的数量(即绘制拥有最高成员资格的前5个社区)或列出特定社区的成员 library(igraph) edges <- read.csv('http://
library(igraph)
edges <- read.csv('http://dl.dropbox.com/u/23776534/Facebook%20%5BEdges%5D.csv')
all<-graph.data.frame(edges)
summary(all)
all_eb <- edge.betweenness.community(all)
mods <- sapply(0:ecount(all), function(i) {
all2 <- delete.edges(all, all_eb$removed.edges[seq(length=i)])
cl <- clusters(all2)$membership
modularity(all, cl)
})
plot(mods, type="l")
all2<-delete.edges(all, all_eb$removed.edges[seq(length=which.max(mods)-1)])
V(all)$color=clusters(all2)$membership
all$layout <- layout.fruchterman.reingold(all,weight=V(all)$weigth)
plot(all, vertex.size=4, vertex.label=NA, vertex.frame.color="black", edge.color="grey",
edge.arrow.size=0.1,rescale=TRUE,vertex.label=NA, edge.width=.1,vertex.label.font=NA)
库(igraph)
边通过仔细查看您正在使用的函数的文档,可以发现其中几个问题。例如,“值”部分中的集群文档描述了函数将返回的内容,其中有几个可以回答您的问题。除了文档之外,您始终可以使用str
函数分析任何特定对象的组成
也就是说,要获取特定社区中的成员或成员数量,您可以查看clusters
函数返回的成员身份
对象(您已经在使用它来分配颜色)。比如:
summary(clusters(all2)$membership)
将描述正在使用的集群的ID。在示例数据中,看起来您有ID范围为0到585的集群,总共586个集群。(请注意,使用当前使用的着色方案无法非常准确地显示这些内容。)
要确定每个簇中的顶点数,可以查看csize
组件,该组件也是由簇返回的。在本例中,它是一个长度为586的向量,为每个计算的簇存储一个大小。所以你可以用
clusters(all2)$csize
获取群集的大小列表。请注意,如前所述,您的集群从0(“零索引”)开始,而R向量从1(“一索引”)开始,因此您需要将这些索引移动1。例如,clusters(all2)$csize[5]
返回ID为4的集群大小
要列出任何簇中的顶点,您只需要找到前面提到的成员资格
组件中与所讨论的簇匹配的ID。因此,如果我想在集群128中找到顶点(根据集群(all2)$csize[129]
,其中有21个顶点),我可以使用:
which(clusters(all2)$membership == 128)
length(which(clusters(all2)$membership == 128)) #21
要检索该簇中的顶点,我可以使用V
函数并传入我刚刚计算的索引,这些索引是该簇的成员:
> V(all2)[clusters(all2)$membership == 128]
Vertex sequence:
[1] "625591221 - Clare Clancy"
[2] "100000283016052 - Podge Mooney"
[3] "100000036003966 - Jennifer Cleary"
[4] "100000248002190 - Sarah Dowd"
[5] "100001269231766 - LirChild Surfwear"
[6] "100000112732723 - Stephen Howard"
[7] "100000136545396 - Ciaran O Hanlon"
[8] "1666181940 - Evion Grizewald"
[9] "100000079324233 - Johanna Delaney"
[10] "100000097126561 - Órlaith Murphy"
[11] "100000130390840 - Julieann Evans"
[12] "100000216769732 - Steffan Ashe"
[13] "100000245018012 - Tom Feehan"
[14] "100000004970313 - Rob Sheahan"
[15] "1841747558 - Laura Comber"
[16] "1846686377 - Karen Ni Fhailliun"
[17] "100000312579635 - Anne Rutherford"
[18] "100000572764945 - Lit Đ Jsociety"
[19] "100003033618584 - Fall Ball"
[20] "100000293776067 - James O'Sullivan"
[21] "100000104657411 - David Conway"
这将涵盖你的基本问题。其他问题与图论更为相关。我不知道如何使用iGraph来管理要创建的集群数量,但是有人可能会向您指出一个能够做到这一点的包。你可能会更成功地将其作为一个单独的问题发布,无论是在这里还是在其他地点
关于你想要迭代所有可能的社区的第一点,我想你会发现对于一个很大的图来说这是不可行的。5个不同簇的成员资格向量的可能排列数为5^n,其中n是图的大小。如果你想找到“所有可能的社区”,如果我的心算正确的话,这个数字实际上是O(n^n)。从本质上讲,即使给定了大量的计算资源,也不可能在任何规模合理的网络上彻底计算出这一点。因此,我认为您最好使用某种智能/优化来确定图表中表示的社区数量,就像clusters
函数所做的那样。关于OPs问题中的“如何控制社区数量”,我使用社区上的cut_at函数将生成的层次结构切割成所需数量的组。我希望有人能证实我在做一些理智的事情。也就是说,考虑以下内容:
#Generate graph
adj.mat<- matrix(,nrow=200, ncol=200) #empty matrix
set.seed(2)
##populate adjacency matrix
for(i in 1:200){adj.mat[i,sample(rep(1:200), runif(1,1,100))]<-1}
adj.mat[which(is.na(adj.mat))] <-0
for(i in 1:200){
adj.mat[i,i]<-0
}
G<-graph.adjacency(adj.mat, mode='undirected')
plot(G, vertex.label=NA)
##Find clusters
walktrap.comms<- cluster_walktrap(G, steps=10)
max(walktrap.comms$membership) #43
[1] 6 34 13 1 19 19 3 9 20 29 12 26 9 28 9 9 2 14 13 14 27 9 33 17 22 23 23 10 17 31 9 21 2 1
[35] 33 23 3 26 22 29 4 16 24 22 25 31 23 23 13 30 35 27 25 15 6 14 9 2 16 7 23 4 18 10 10 22 27 27
[69] 23 31 27 32 36 8 23 6 23 14 19 22 19 37 27 6 27 22 9 14 4 22 14 32 33 27 26 14 21 27 22 12 20 7
[103] 14 26 38 39 26 3 14 23 22 14 40 9 5 19 29 31 26 26 2 19 6 9 1 9 23 4 14 11 9 22 23 41 10 27
[137] 22 18 26 14 8 15 27 10 5 33 21 28 23 22 13 1 22 24 14 18 8 2 18 1 27 12 22 34 13 27 3 5 27 25
[171] 1 27 13 34 8 10 13 5 17 17 25 6 19 42 31 13 30 32 15 30 5 11 9 25 6 33 18 33 43 10
并以此为基础进行切割。我任意选择了6个切割,但是,你现在有了更粗糙的簇
cut_at(walktrap.comms, no=6)
[1] 4 2 5 4 5 5 3 5 3 4 3 5 5 3 5 5 3 1 5 1 1 5 1 6 1 1 1 4 6 5 5 2 3 4 1 1 3 5 1 4 6 6 3 1 5 5 1 1 5 4 3 1
[53] 5 2 4 1 5 3 6 3 1 6 6 4 4 1 1 1 1 5 1 4 3 3 1 4 1 1 5 1 5 2 1 4 1 1 5 1 6 1 1 4 1 1 5 1 2 1 1 3 3 3 1 5
[105] 3 3 5 3 1 1 1 1 3 5 2 5 4 5 5 5 3 5 4 5 4 5 1 6 1 3 5 1 1 1 4 1 1 6 5 1 3 2 1 4 2 1 2 3 1 1 5 4 1 3 1 6
[157] 3 3 6 4 1 3 1 2 5 1 3 2 1 5 4 1 5 2 3 4 5 2 6 6 5 4 5 3 5 5 4 4 2 4 2 3 5 5 4 1 6 1 2 4
您是否也可以提供创建all
对象的代码?或者,如果它太大,至少是它的一些小版本?“我很难重新创建这个问题。@JeffAllen,“抱歉”添加了一些facebook数据样本,我正在处理的实际数据大约是这个的50倍。。Thanks@JeffAllen,非常感谢,这帮了大忙。您会注意到,为了提高性能,我更改了上面的社区检测方法。有没有关于我如何解决匹配问题的建议?当然有。我开始对修改后的问题和目标有点困惑。我建议把每件事都简化成一两个不同的问题,然后再问一个新问题。@JeffAllen,没问题,谢谢!
#Generate graph
adj.mat<- matrix(,nrow=200, ncol=200) #empty matrix
set.seed(2)
##populate adjacency matrix
for(i in 1:200){adj.mat[i,sample(rep(1:200), runif(1,1,100))]<-1}
adj.mat[which(is.na(adj.mat))] <-0
for(i in 1:200){
adj.mat[i,i]<-0
}
G<-graph.adjacency(adj.mat, mode='undirected')
plot(G, vertex.label=NA)
##Find clusters
walktrap.comms<- cluster_walktrap(G, steps=10)
max(walktrap.comms$membership) #43
[1] 6 34 13 1 19 19 3 9 20 29 12 26 9 28 9 9 2 14 13 14 27 9 33 17 22 23 23 10 17 31 9 21 2 1
[35] 33 23 3 26 22 29 4 16 24 22 25 31 23 23 13 30 35 27 25 15 6 14 9 2 16 7 23 4 18 10 10 22 27 27
[69] 23 31 27 32 36 8 23 6 23 14 19 22 19 37 27 6 27 22 9 14 4 22 14 32 33 27 26 14 21 27 22 12 20 7
[103] 14 26 38 39 26 3 14 23 22 14 40 9 5 19 29 31 26 26 2 19 6 9 1 9 23 4 14 11 9 22 23 41 10 27
[137] 22 18 26 14 8 15 27 10 5 33 21 28 23 22 13 1 22 24 14 18 8 2 18 1 27 12 22 34 13 27 3 5 27 25
[171] 1 27 13 34 8 10 13 5 17 17 25 6 19 42 31 13 30 32 15 30 5 11 9 25 6 33 18 33 43 10
plot(as.hclust(walktrap.comms), label=F)
cut_at(walktrap.comms, no=6)
[1] 4 2 5 4 5 5 3 5 3 4 3 5 5 3 5 5 3 1 5 1 1 5 1 6 1 1 1 4 6 5 5 2 3 4 1 1 3 5 1 4 6 6 3 1 5 5 1 1 5 4 3 1
[53] 5 2 4 1 5 3 6 3 1 6 6 4 4 1 1 1 1 5 1 4 3 3 1 4 1 1 5 1 5 2 1 4 1 1 5 1 6 1 1 4 1 1 5 1 2 1 1 3 3 3 1 5
[105] 3 3 5 3 1 1 1 1 3 5 2 5 4 5 5 5 3 5 4 5 4 5 1 6 1 3 5 1 1 1 4 1 1 6 5 1 3 2 1 4 2 1 2 3 1 1 5 4 1 3 1 6
[157] 3 3 6 4 1 3 1 2 5 1 3 2 1 5 4 1 5 2 3 4 5 2 6 6 5 4 5 3 5 5 4 4 2 4 2 3 5 5 4 1 6 1 2 4