代码之家  ›  专栏  ›  技术社区  ›  Chris T.

将多个节点向量合并为边列表并将其转换为邻接矩阵

  •  3
  • Chris T.  · 技术社区  · 7 年前

    我想映射一些关系圈(由一系列关系组成) id

    circle_1 = c(1, 3, 5)
    circle_2 = c(17, 22, 35, 49)
    circle_3 = c(2, 9)
    circle_4 = c(12, 28, 33)
    circle_5 = c(1, 3, 8, 16, 40)
    
    d_mat = matrix(ncol = 2)
    
    for (i in 1:5) {
    #extract id from list
    dat = get(paste("circle", i, sep="_"))
    #convert to edgelist, each pair is unique
    dat_t = t(combn(dat, 2))
    #rbind edge list together
    edge_list <- rbind(d_mat, dat_t)
    }
    

    然而,输出 edge_list circle_5

    此外,假设这五个圆是从一组50人中画出来的,我如何将这些边列表的值映射到50×50邻接矩阵的相应单元格(我想 make_graph as_adjacency_matrix 作用于 igraph 应该做的把戏,但我现在不知道怎么做)

    circle_1 ,这意味着1和3在这个50人的网络中链接了两次。如何聚合此计数频率并将邻接矩阵转换为加权矩阵?

    2 回复  |  直到 7 年前
        1
  •  2
  •   gfgm    7 年前

    您可以在开始时通过组合边列表来完成,然后直接创建矩阵。

    circle_1 = c(1, 3, 5)
    circle_2 = c(17, 22, 35, 49)
    circle_3 = c(2, 9)
    circle_4 = c(12, 28, 33)
    circle_5 = c(1, 3, 8, 16, 40)
    
    # lets put all the circles in a list for convenience
    circles <- list(circle_1, circle_2, circle_3,
                    circle_4, circle_5)
    
    # we will lapply along the list, get the complete set of 
    # edges with combn, and then rbind all the resulting
    # structures together
    edge_list <- do.call(rbind, lapply(circles, function(circ){t(combn(circ, 2))}))
    
    # we convert to a data.frame and set the factor levels
    # such that R knows these are nodes from a set of 50 nodes
    edge_list <- data.frame(from = factor(edge_list[,1], levels=1:50),
                            to = factor(edge_list[,2], levels=1:50))
    # take a look
    head(edge_list)
    #>   from to
    #> 1    1  3
    #> 2    1  5
    #> 3    3  5
    #> 4   17 22
    #> 5   17 35
    #> 6   17 49
    # we can just use table to make the adjacency matrix. R will create
    # a row/column for each level of the factor. We look at the first
    # 6x6 entries
    table(edge_list)[1:6,1:6] # luckily entry (1,3) = 2 as we hoped
    #>     to
    #> from 1 2 3 4 5 6
    #>    1 0 0 2 0 1 0
    #>    2 0 0 0 0 0 0
    #>    3 0 0 0 0 1 0
    #>    4 0 0 0 0 0 0
    #>    5 0 0 0 0 0 0
    #>    6 0 0 0 0 0 0
    

    这个邻接矩阵是上三角形的。如果希望邻接矩阵像反射无向图一样对称,可以使用 adj.mat[lower.tri(adj.mat)] <- adj.mat[upper.tri(adj.mat)] .

    # to convert to purely binary
    adj.mat <- table(edge_list)
    adj.mat.bin <- ifelse(adj.mat>1, 1, adj.mat)
    adj.mat.bin[1:6,1:6]
    #>     to
    #> from 1 2 3 4 5 6
    #>    1 0 0 1 0 1 0
    #>    2 0 0 0 0 0 0
    #>    3 0 0 0 0 1 0
    #>    4 0 0 0 0 0 0
    #>    5 0 0 0 0 0 0
    #>    6 0 0 0 0 0 0
    

    于2018年11月16日由 reprex package (v0.2.1)

        2
  •  1
  •   Henrik plannapus    7 年前

    我从@gfgm借用顶点列表(“圆”)并使用 igraph 功能。

    使用鼠标在顶点列表上循环 lapply make_full_graph n 等于向量的长度。设置顶点的名称( V(g)$name ). 转换为“边缘列表”( as_edgelist ). rbind

    library(igraph)
    m <- do.call(rbind, lapply(circles, function(vert){
      g <- make_full_graph(n = length(vert))
      V(g)$name <- vert
      as_edgelist(g)
    }))
    

    设置 factor “从”和“到”顶点的级别,并使用 table (类似于@gfgm)

    tt <- table(factor(m[ , 1], levels = 1:50),
                factor(m[ , 2], levels = 1:50)) 
    
    t[1:8, 1:16]
    #   1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
    # 1 0 0 2 0 1 0 0 1 0  0  0  0  0  0  0  1
    # 2 0 0 0 0 0 0 0 0 1  0  0  0  0  0  0  0
    # 3 0 0 0 0 1 0 0 1 0  0  0  0  0  0  0  1
    # 4 0 0 0 0 0 0 0 0 0  0  0  0  0  0  0  0
    # 5 0 0 0 0 0 0 0 0 0  0  0  0  0  0  0  0
    # 6 0 0 0 0 0 0 0 0 0  0  0  0  0  0  0  0
    # 7 0 0 0 0 0 0 0 0 0  0  0  0  0  0  0  0
    # 8 0 0 0 0 0 0 0 0 0  0  0  0  0  0  0  1