【问题标题】:Join two adjacency matrices and retain values加入两个邻接矩阵并保留值
【发布时间】:2019-09-08 04:06:51
【问题描述】:

按照this question,是否可以连接两个邻接矩阵,并保留新行和新列的值?

以参考中的示例为基础,mat1mat2 的联合使用 0 初始化新添加的行和列中的值。我想用邻接矩阵中的值初始化它们,并保留该信息。

> mat1
      Tommy Roy Addy Sam
Tommy     0   1    0  -1
Roy      -1  -1    1   0
Addy      1   0   -1   0
Sam       0   0   -1   1
> mat2
     Mike Roy Addy Sam Dan
Mike    0   1    0  -1   0
Roy    -1  -1    1   0   1
Addy    1   0   -1   0  -1
Sam     0   0   -1   1   0
Dan     1   0    0  -1   1

complete_matrix <- function(mat, ref) {
  dif <- setdiff(rownames(ref), rownames(mat))
  mat <- rbind(mat, matrix(0, length(dif), ncol(mat), dimnames = list(dif, NULL)))
  mat <- cbind(mat, matrix(0, nrow(mat), length(dif), dimnames = list(NULL, dif)))
  return(mat)
}

> complete_matrix(mat2, mat1)
      Mike Roy Addy Sam Dan Tommy
Mike     0   1    0  -1   0     0
Roy     -1  -1    1   0   1     0
Addy     1   0   -1   0  -1     0
Sam      0   0   -1   1   0     0
Dan      1   0    0  -1   1     0
Tommy    0   0    0   0   0     0

例如,我希望 complete_matrix(mat2, mat1) 产生以下结果(观察 Tommy 行和列):

      Mike Roy Addy Sam Dan Tommy
Mike     0   1    0  -1   0     0
Roy     -1  -1    1   0   1     1
Addy     1   0   -1   0  -1     0
Sam      0   0   -1   1   0    -1
Dan      1   0    0  -1   1     0
Tommy    0   1    0  -1   0     0

dput 为 c&P:

mat1 <- structure(c(0L, -1L, 1L, 0L, 1L, -1L, 0L, 0L, 0L, 1L, -1L, -1L, 
            -1L, 0L, 0L, 1L), .Dim = c(4L, 4L), .Dimnames = list(c("Tommy", 
                                                                   "Roy", "Addy", "Sam"), c("Tommy", "Roy", "Addy", "Sam")))
mat2 <- structure(c(0L, -1L, 1L, 0L, 1L, 1L, -1L, 0L, 0L, 0L, 0L, 1L, 
                    -1L, -1L, 0L, -1L, 0L, 0L, 1L, -1L, 0L, 1L, -1L, 0L, 1L), .Dim = c(5L, 
                                                                                       5L), .Dimnames = list(c("Mike", "Roy", "Addy", "Sam", "Dan"), 
                                                                                                             c("Mike", "Roy", "Addy", "Sam", "Dan")))

【问题讨论】:

  • 如果存在差异,您希望发生什么?例如,mat1 中的 Addy/Sam 值为 1,mat2 中的值为 0? (或者我们可以假设没有差异?)
  • @Gregor,这是一个很好的问题。就我的目的而言,永远不会有差异。这是一个巨大的邻接矩阵计算的小代表,我将它分成可管理的部分,然后连接成一个巨大的稀疏矩阵。

标签: r matrix adjacency-matrix


【解决方案1】:

您可以使用 igraph 包的 union 函数来完成此操作,这需要先将矩阵转换为图形,然后再将结果图形转换回矩阵:

library(igraph)

g1 = graph_from_adjacency_matrix(mat1,weighted=T)
g2 = graph_from_adjacency_matrix(mat2,weighted=T)
g3 = union(g1,g2)

union 不会自动合并 g1 和 g2 的权重,而是将它们作为单独的属性 weight_1weight_2。我们可以通过取两个权重之间的最小值来组合它们,如果两个矩阵之间没有差异,这只是一种合并它们并删除NA值的方法。

E(g3)$weight = pmin(E(g3)$weight_1,E(g3)$weight_2,na.rm=T)
res = as.matrix(as_adj(g3,attr="weight"))

      Tommy Roy Addy Sam Mike Dan
Tommy     0   1    0  -1    0   0
Roy      -1  -1    1   0   -1   1
Addy      1   0   -1   0    1  -1
Sam       0   0   -1   1    0   0
Mike      0   1    0  -1    0   0
Dan       0   0    0  -1    1   1

【讨论】:

    【解决方案2】:

    我愿意:

    1. 将矩阵转换为单独的对矩阵(即对值),即矩阵转长
    2. 绑定它们,
    3. 决定如何处理重复的配对(这里我只取第一个值...)
    4. 然后扩散到宽阔的背部。

    更新:可能会运行 distinct() 并将 value 添加到:group_by(ind_1, ind_2, value)。加号spread()中填0?

    例子:

    library(tidyverse)
    mat1 <- structure(c(0L, -1L, 1L, 0L, 1L, -1L, 0L, 0L, 0L, 1L, -1L, -1L, 
                        -1L, 0L, 0L, 1L), .Dim = c(4L, 4L), .Dimnames = list(c("Tommy", 
                                                                               "Roy", "Addy", "Sam"), c("Tommy", "Roy", "Addy", "Sam")))
    mat2 <- structure(c(0L, -1L, 1L, 0L, 1L, 1L, -1L, 0L, 0L, 0L, 0L, 1L, 
                        -1L, -1L, 0L, -1L, 0L, 0L, 1L, -1L, 0L, 1L, -1L, 0L, 1L), .Dim = c(5L, 
                                                                                           5L), .Dimnames = list(c("Mike", "Roy", "Addy", "Sam", "Dan"), 
                                                                                                                 c("Mike", "Roy", "Addy", "Sam", "Dan")))
    
    mat1_l <- mat1 %>% 
      as.data.frame() %>% 
      rownames_to_column(var = "ind_1") %>% 
      as_tibble() %>% 
      gather(ind_2, value, -ind_1)
    
    mat2_l <- mat2 %>% 
      as.data.frame() %>% 
      rownames_to_column(var = "ind_1") %>% 
      as_tibble() %>% 
      gather(ind_2, value, -ind_1)
    
    
    rbind(mat1_l, mat2_l) %>% 
      group_by(ind_1, ind_2) %>% 
      slice(1) %>% 
      ungroup() %>% 
      spread(ind_2, value)
    #> # A tibble: 6 x 7
    #>   ind_1  Addy   Dan  Mike   Roy   Sam Tommy
    #>   <chr> <int> <int> <int> <int> <int> <int>
    #> 1 Addy     -1    -1     1     0     0     1
    #> 2 Dan       0     1     1     0    -1    NA
    #> 3 Mike      0     0     0     1    -1    NA
    #> 4 Roy       1     1    -1    -1     0    -1
    #> 5 Sam      -1     0     0     0     1     0
    #> 6 Tommy     0    NA    NA     1    -1     0
    

    【讨论】:

    • 这也有效。虽然我没有在问题中提到它,但由于内存问题,我需要一种适用于稀疏矩阵的方法。不过感谢您的回答!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-07-31
    • 1970-01-01
    • 1970-01-01
    • 2016-04-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多