在R中的矩阵中找到所有“周期/派系”的最佳方法是什么?

时间:2015-12-08 23:43:21

标签: r

假设我有一个带有0和1的方阵,如下例所示:

    1 2 3 4 5 6

1   0 1 0 1 0 0
2   1 0 0 1 0 0
3   0 0 0 0 0 0
4   1 1 0 0 0 0
5   0 0 0 0 0 1
6   0 0 0 0 1 0

我们可以认为这是一个邻接矩阵,有6个顶点,所有对角元素都必须为0.当然,矩阵必须关于对角线对称。

在R中,给出一堆具有不同大小的矩阵,找到每个矩阵中的所有“派系”并给出每个集团的成员,最有效的方法是什么? ('clique'是指一组顶点,每个顶点都有一个边缘到集合中的每个顶点)例如,在上面的矩阵中,有两个集团;通过行/列号表示顶点,派系是(1,2,4)和(5,6)。因此,对于输出,我想要每个集团中所有顶点(行或列名称)的列表,用于该矩阵中的所有派系。我想为大量不同大小的矩阵做这个(尽管所有矩阵都是方矩阵)。有关最佳方法的任何想法是什么?

我一直在考虑在for循环中使用for循环,但是因为可能派系的大小是不确定的(但最多可以等于矩阵中行/列的数量)让我觉得我可能我需要使用while循环,但我不确定它是多么精确。

我将粘贴一些我刚刚编写的代码,这些代码应该按照我所描述的方式进行操作,其中列表'cliquelist'包含循环结束时矩阵中的所有派系。邻接矩阵称为“mat”。

cliquelist <- NULL

for(i in 1:nrow(mat)){
  for(j in 1:ncol(mat)){
    if(mat[i,j]==1){
      clique <- c(i, j)
      pool <- j:ncol(mat)
      while(length(pool)>0) {
        add <- which(mat[,pool[1]]==1)
        if(length(add)==0){
          pool <- NULL
        }else{
          pool <- pool[which(!pool %in% add)]
          clique <- c(clique, add)
        }
      }
      cliquelist[length(cliquelist)+1] <- clique
    }
  }
}

我确定这段代码中有一些错误;在上面展示的示例矩阵中,我还没弄清楚它们是什么,因为它仍在运行(经过几分钟),所以我怀疑它们的某个地方存在无限循环。

但它有几个问题,甚至让我不愿意回去调试它。 1)最明显的是,它会将每个clique添加到列表中的次数与列表中的元素一样多,因此存在大量冗余。 2)它不会过滤掉较大派系中较小的派系。所以,如果一个集团由顶点1,3和5组成,那么类似上面代码的东西将返回(1,3),(1,5),(3,5),(1,3,5)等但我只希望独特的派系不被包含在更大的派系中。我想知道在R中是否有一种不同的,更有效的方法。

非常感谢任何建议。

1 个答案:

答案 0 :(得分:2)

igraph库是为图形分析而定制的。使用dat作为矩阵的名称:

library(igraph)
z <- graph.adjacency(dat)
cluster_walktrap(z)

IGRAPH clustering walktrap, groups: 3, mod: 0.38
+ groups:
  $`1`
  [1] "X5" "X6"

  $`2`
  [1] "X1" "X2" "X4"

  $`3`
  [1] "X3"

这是一个情节:

plot(z)

enter image description here