Соедините две матрицы смежности и сохраните значения - PullRequest
1 голос
/ 17 апреля 2019

После этого вопроса , возможно ли объединить две матрицы смежности и сохранить значения новых строк и столбцов?

Опираясь на пример в ссылке, объединение mat1 и mat2 инициализируют значения во вновь добавленных строках и столбцах с 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")))

Ответы [ 2 ]

3 голосов
/ 18 апреля 2019

Вы можете сделать это, используя функцию union пакета igraph, которая потребует сначала преобразовать ваши матрицы в графы, а затем преобразовать полученный граф обратно в матрицу:

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_1 и weight_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 голосов
/ 18 апреля 2019

Я хотел бы:

  1. превратить матрицы в отдельные пары-матрицы (т. Е. Парные значения), то есть матрицы в длинные
  2. связать их,
  3. решитьчто делать для повторяющихся пар (здесь я просто беру первое значение ...)
  4. , затем распространился на широкую спину.

Обновление: вероятно, запустится distinct() и добавится значение в: group_by(ind_1, ind_2, value).Плюс заполните 0 в spread()?

Пример:

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
...