【问题标题】:Get edge list that includes alter's alters获取包含alter的alter的边缘列表
【发布时间】:2020-01-24 19:28:49
【问题描述】:

我需要一个包含三列的数据框:i、j(alter)和 k(j's alter)。我有一个邻接矩阵(下面的示例)。从那里我可以得到一个图形对象并提取边缘列表。如何操作数据以获得如下 WANT 数据框的输出?

HAVE(矩阵和边列表):

      1   2   3   4   5   

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


g <- graph_from_adjacency_matrix(mat)

get.edgelist(g)


i   j

1   4
2   3
2   4
2   5
4   1
4   2
4   5
5   1
5   2
5   4

WANT(ijk 边缘列表):

i j k
1 4 2
1 4 5
2 4 1
2 4 5
4 2 3
4 5 1
4 5 2
5 1 4 
5 2 3
5 2 4
5 4 1
5 4 2

ijk 边缘列表应该是所有可能的 ij 三元组,不包括自循环(例如:1 4 1)

【问题讨论】:

    标签: r dplyr igraph data-manipulation edge-list


    【解决方案1】:

    数据:

    as.matrix(read.table(text = "0   0   0   1   0  
                                 0   0   1   1   1   
                                 0   0   0   0   0   
                                 1   1   0   0   1   
                                 1   1   0   1   0",
                         header = F, stringsAsFactors = F)) -> m1
    
    dimnames(m1) <- list(1:5, 1:5)
    

    库:

    library(igraph) 
    library(dplyr)
    library(tidyr)
    library(magrittr)
    

    解决方案:

    g1 <- graph_from_adjacency_matrix(m1)
    e1 <- get.edgelist(g1) %>% as.data.frame %>% mutate_if(is.factor, as.character)
    
    e1 %>% 
      group_by(V1) %>% 
      nest(V2) %>% 
      right_join(e1,.,by = c("V2"="V1")) %>%  
      unnest %>% 
      filter(V1 != V21) %>% 
      set_colnames(c("i", "j", "k"))
    

    输出:

    #>    i j k
    #> 1  1 4 2
    #> 2  1 4 5
    #> 3  2 4 1
    #> 4  2 4 5
    #> 5  2 5 1
    #> 6  2 5 4
    #> 7  4 2 3
    #> 8  4 2 5
    #> 9  4 5 1
    #> 10 4 5 2
    #> 11 5 1 4
    #> 12 5 2 3
    #> 13 5 2 4
    #> 14 5 4 1
    #> 15 5 4 2
    

    【讨论】:

      【解决方案2】:

      我实际上能够使用 igraph 和 dplyr 找到一种方法:

      # make graph of matrix
      g <- graph_from_adjacency_matrix(mat)
      
      
      # put edgelist into two objects, one where columns are "i, j" and the other "j, k"
      df1 <- get.edgelist(g) %>%
             as.data.frame() %>%
             select(i = V1, j = V2)
      
      df2 <- get.edgelist(g) %>%
             as.data.frame() %>%
             select(j = V1, k = V2)
      
      # combine the dataframes, filter out rows where i and k are the same observation
      df_combn <- inner_join(df1, df2, by = c("j" = "j")) %>%
                  mutate_all(as.character) %>%
                  filter(., !(i == k))
      

      【讨论】:

      • 不错的一个。我使用nest 的唯一原因是向您展示可以以更清晰的格式获得输出。 (免责声明:我实际上看到了你的inner_join 并切换到right_join)干杯。 +1
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-03-10
      • 1970-01-01
      • 2014-03-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多