【问题标题】:Converting a binary matrix into groups将二进制矩阵转换为组
【发布时间】:2015-06-01 03:01:30
【问题描述】:

这是一个看似简单的问题,但我想不出答案。这是最简单的情况:

考虑以下矩阵:

friendMatrix  <- matrix(c(1,1,0,0,0,     
                          1,1,1,0,0,
                          0,1,1,0,0,
                          0,0,0,1,1,
                          0,0,0,1,1),nrow=5)

看起来像这样

     [,1] [,2] [,3] [,4] [,5]
[1,]    1    1    0    0    0 
[2,]    1    1    1    0    0
[3,]    0    1    1    0    0
[4,]    0    0    0    1    1
[5,]    0    0    0    1    1

我想做的是使用这个矩阵来识别朋友组,其中 1 表示友谊。组是基于组内的任何连接形成的,而不仅仅是一级连接(即 1 是 2 的朋友,2 是 3 的朋友但不是 1,但它们都在同一个组中)。如果一行只与它自己相关联,那么它就是它自己的组。我想在这些组中创建一个指示成员资格的data.frame(使用行号作为ID)(一个数字可以作为ID,我只是使用字母以避免混淆)。对于此示例,应如下所示:

row  group
 1    A
 2    A
 3    A
 4    B
 5    B

我考虑过一些聚类算法,但这似乎有点过头了,因为这些组定义明确且显而易见。

【问题讨论】:

    标签: r


    【解决方案1】:

    以下内容将使您能够可视化关系网络,仍在研究如何提取组。

    require(networkD3)
    require(reshape2)
    
    melted <- melt(friendMatrix)
    relationships <- subset(melted, value == 1)
    relationships
    #    Var1 Var2 value
    # 1     1    1     1
    # 2     2    1     1
    # 6     1    2     1
    # 7     2    2     1
    # 8     3    2     1
    # 12    2    3     1
    # 13    3    3     1
    # 19    4    4     1
    # 20    5    4     1
    # 24    4    5     1
    # 25    5    5     1
    
    simpleNetwork(relationships)
    

    【讨论】:

      【解决方案2】:

      改编几年前的my answer to a similar question,您可以使用 RBGL 包来识别您所追求的“连接组件”:

      library(RBGL)
      m <- which(friendMatrix==1, arr.ind=TRUE)
      g <- ftM2graphNEL(m)
      cc <- connectedComp(g)
      names(cc) <- LETTERS[seq_along(cc)]
      ld <- lapply(seq_along(cc), 
                   function(i) data.frame(row = cc[[i]], group = names(cc)[i]))
      do.call(rbind, ld)
      #   row group
      # 1   1     A
      # 2   2     A
      # 3   3     A
      # 4   4     B
      # 5   5     B
      

      对于基于 igraph 的替代解决方案,see here

      【讨论】:

        【解决方案3】:

        这是另一个选择:

        library(igraph)
        g <- graph.adjacency(friendMatrix, "undirected")
        (group <- clusters(g)$membership)
        # [1] 1 1 1 2 2
        V(g)$color <- group + 1
        plot(g)
        

        【讨论】:

          【解决方案4】:

          使用igraph 创建图并通过对结果图的连接组件进行分组来创建集群:

          library(igraph)
          g1 <- graph.adjacency( friendMatrix )
          cl <- clusters(g1)$mem
          ## Display the clusters in a data.frame as OP excpeted
          data.frame(row=seq_along(cl),group=LETTERS[cl])
          
             row group
          1   1     A
          2   2     A
          3   3     A
          4   4     B
          5   5     B
          

          【讨论】:

          • 回答了我的问题,还向我介绍了一个非常有用的包
          • 这个解决方案有 Python 版本吗?
          猜你喜欢
          • 2022-01-23
          • 2020-04-21
          • 1970-01-01
          • 2019-05-02
          • 1970-01-01
          • 2016-03-06
          • 1970-01-01
          • 2013-05-28
          • 1970-01-01
          相关资源
          最近更新 更多