识别并量化igraph中的簇类型

时间:2019-03-12 15:28:31

标签: r igraph

我有以下图形:

enter image description here

这是根据给定的数据得出的:

K01 <- cbind(c(1, 3, 4, 6, 7, 8, 9, 11, 13, 14),
         c(2, 4, 5, 7, 8, 6, 10, 12, 14, 15))
K02 <- graph_from_edgelist(K01, directed = FALSE)

我希望能够量化图中所有子群集的数量和类型。因此,我希望能够通过大小相同或不圆形的节点或有关节点的其他属性来分离相同大小的群集。

我可以很容易地获得群集大小:

K03 <- components(K02)
K04 <- groups(K03)

但这并不能帮助我按群集结构进行排序。

2 个答案:

答案 0 :(得分:0)

我不确定,但是只要没有loops,如果组中边的数量等于或大于顶点的数量,它就是圆形的。

with(do.call(rbind, lapply(K04, function(x){
    g = induced_subgraph(K02, x)
    data.frame(n = vcount(g),
               type = ifelse(ecount(g) >= vcount(g), "circular", "simple"))
})), table(n, type))
#   type
#n   simple circular
#  2      3        0
#  3      2        1

答案 1 :(得分:0)

因此,感谢d.b在此方面的帮助。我分解并编写了一个函数,该函数可以执行我试图完成的任务。这有点冗长,可能有点笨拙,但似乎可以满足我的需要。

######
# take an igraph graph
# and return a nested list the length of the number of unique cluster structures
# where each list item is a list of clusters that shared that structure
# names ?
######

CategorizeSubGraphs <- function(IGraph) {

  cat("\n")
  # get groups
  IGroups <- groups(components(IGraph))

  Structures <- vector("list",
                       length = length(IGroups))
  StructNames <- vector("list",
                        length = length(IGroups))
  AllSubGraphs <- vector("list",
                         length = length(IGroups))

  # initialize a progress bar
  pBar <- txtProgressBar(style = 1L)

  # Get all graph structures, remove names for unique()
  for (i in seq_along(Structures)) {
    AllSubGraphs[[i]] <- induced_subgraph(graph = IGraph,
                                         vids = IGroups[[i]])
    Structures[[i]] <- AllSubGraphs[[i]][seq(length(AllSubGraphs[[i]][1]))]
    StructNames[[i]] <- dimnames(Structures[[i]])[[1]]
    dimnames(Structures[[i]]) <- list(NULL,
                                      NULL)
    setTxtProgressBar(pb = pBar,
                      value = i / length(Structures))
  }
  cat("\n")
  # categorize by structure
  GraphSizes <- sapply(unique(Structures),
                       function(x) nrow(x))
  AllSizes <- sapply(Structures,
                     function(x) nrow(x))
  GraphTemplates <- unique(Structures)

  Result <- vector("list",
                   length = length(GraphTemplates))
  StructureCategory <- vector("integer",
                              length = length(AllSizes))
  # assign each subgraph to a category
  for (i in seq_along(StructureCategory)) {
    Catch <- which(GraphSizes == AllSizes[i])
    if (length(Catch) == 1L) {
      StructureCategory[i] <- Catch
    } else {
      for (j in seq_along(Catch)) {
        if (all(GraphTemplates[[Catch[j]]] == Structures[[i]])) {
          StructureCategory[i] <- Catch[j]
        }
      }
    }
    setTxtProgressBar(pb = pBar,
                      value = i / length(StructureCategory))
  }

  Count <- rep(0L,
               length(Result))

  ResultSizes <- sapply(unique(StructureCategory),
                        function(x) length(which(StructureCategory == x)))

  for (i in seq_along(Result)) {
    Result[[i]] <- vector("list",
                          length = ResultSizes[i])
  }

  # collect all subgraphs into their distinct categories

  for (i in seq_along(StructureCategory)) {
    Count[StructureCategory[i]] <- Count[StructureCategory[i]] + 1L
    Result[[StructureCategory[i]]][[Count[StructureCategory[i]]]] <- AllSubGraphs[[i]]
  }
  cat("\n")
  return(Result)
}

因此,我尝试成功地对给定图中的所有子图进行排序和汇总。

所以给定了:

K01 <- cbind(c(1, 3, 4, 6, 7, 8, 9, 11, 13, 14, 16, 18, 18, 17, 20, 21, 21),
             c(2, 4, 5, 7, 8, 6, 10, 12, 14, 15, 18, 17, 19, 16, 21, 22, 23))
K02 <- graph_from_edgelist(K01,
                           directed = FALSE)

哪个开始于:

enter image description here

K03 <- CategorizeSubGraphs(IGraph = K02)
length(K03) # the number of distinct subgraph types
[1] 5
lengths(K03) # the number of individual subgraphs for each type
[1] 3 2 1 1 1

然后您可以适当地绘制各个子群集/子群集,并从图形对象中获取它们的名称。

我还没有使用具有相互连接的子图的图进行测试,因为我需要使用特定类型的数据,但是如果有人有这个问题,就在这里!