Получить список краев, который включает в себя изменения alter - PullRequest
3 голосов
/ 24 сентября 2019

Мне нужен фрейм данных, который включает три столбца: i, j (изменить) и k (изменить j).У меня есть матрица смежности (образец ниже).Оттуда я могу получить объект графа и извлечь список ребер.Как я могу манипулировать данными, чтобы получить вывод, подобный приведенному ниже фрейму данных WANT?

HAVE (matrix & edgelist):

      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)

Ответы [ 2 ]

1 голос
/ 24 сентября 2019

Данные:

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
1 голос
/ 24 сентября 2019

Я действительно смог получить способ сделать это, используя 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))
...