2016-10-09 17 views
2

У меня есть играф, в котором я хотел бы извлечь все соединения 1-й степени каждого узла вместе со соединениями второй степени. Таблицы должны быть раздельными.Получить соединения 1-й степени и соединения 2-й степени для всех узлов в Igraph

Полный воспроизводимый код с изображением графа ниже:

library(igraph) 
library(visNetwork) 
B = matrix( 
    c(1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 
    0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 
    0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 
    0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 
    0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 
    0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 
    0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 
    0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 1), 
    nrow=10, 
    ncol=10) 
colnames(B) <- c("Alpha", "Bravo", "Colonel", "Demo", "Egg", "Felix", "Gasoline", "Hurricane", "Indigo", "Jab") 
rownames(B) <- c("Alpha", "Bravo", "Colonel", "Demo", "Egg", "Felix", "Gasoline", "Hurricane", "Indigo", "Jab") 

g96e = t(B) %*% B 

i96e = graph.adjacency(g96e, mode = "undirected", weighted = TRUE, diag=FALSE) 
visIgraph(i96e) 

enter image description here

Я хотел бы мой окончательный результат будет dataframe который выглядит следующим образом:

Node ID  1st Degree Connections 
Alpha   Gasoline 
Bravo   Egg 
Bravo   Hurricane 
Colonel   Felix 
Colonel   Indigo 
Demo   Felix 
Demo   Gasoline 
Demo   Jab 
Egg    Bravo 
Felix   Colonel 
Felix   Demo 
Felix   Hurricane 
Felix   Indigo 
Gasoline  Alpha 
Gasoline  Demo 
Gasoline  Jab 
Hurricane  Bravo 
Hurricane  Felix 
Indigo   Colonel 
Indigo   Felix 
Jab    Demo 
Jab    Gasoline 

А потом другой фрейм с двумя соединениями второй степени и в идеале показывающий, где источник связи 2-й степени, но если это невозможно, то просто 2 nd степень подключение сделаю.

Node ID  2nd Degree Connections  From 1st Degree Connection 
Alpha    Demo      Gasoline 
Alpha    Jab      Gasoline 
Bravo    Felix     Hurricane 
Colonel    Demo      Felix 
Colonel    Hurricane    Felix 
Colonel    Indigo     Felix 
Colonel    Felix     Indigo 
Demo    Colonel     Felix 
Demo    Hurricane    Felix 
Demo    Indigo     Felix 
Demo    Alpha     Gasoline 
Demo    Jab      Gasoline 
Demo    Gasoline     Jab 
Egg     Hurricane    Bravo 
Felix    Indigo     Colonel 
Felix    Gasoline     Demo 
Felix    Jab      Demo 
Felix    Bravo     Hurricane 
Felix    Colonel     Indigo 
Gasoline   Felix     Demo 
Gasoline   Jab      Demo 
Gasoline   Demo      Jab 
Hurricane   Egg      Bravo 
Hurricane   Colonel     Felix 
Hurricane   Demo      Felix 
Hurricane   Indigo     Felix 
Indigo    Felix     Colonel 
Indigo    Colonel     Felix 
Indigo    Demo      Felix 
Indigo    Hurricane    Felix 
Jab     Felix     Demo 
Jab     Gasoline     Demo 
Jab     Alpha     Gasoline 
Jab     Demo      Gasoline 

Любая помощь была бы замечательной, спасибо!

ответ

2

Первой степень связи, по определению, является другим Vertice подключен к ребрам графа, так что вы можете просто использовать get.edgelist() для получения всех прямых соединений в объекте графа, который является матрицей:

library(igraph); library(dplyr); 

edges <- get.edgelist(i96e) 
edges 

#   [,1]  [,2]  
# [1,] "Alpha" "Gasoline" 
# [2,] "Bravo" "Egg"  
# [3,] "Bravo" "Hurricane" 
# [4,] "Colonel" "Felix"  
# [5,] "Colonel" "Indigo" 
# [6,] "Demo"  "Felix"  
# [7,] "Demo"  "Gasoline" 
# [8,] "Demo"  "Jab"  
# [9,] "Felix" "Hurricane" 
# [10,] "Felix" "Indigo" 
# [11,] "Gasoline" "Jab" 

Список ребер возвращает ребро только один раз для каждого ребра, поэтому, если вы хотите первое соединение для всех вершин, вы можете переключать столбцы from и to и связывать с исходной матрицей граней, что дает более удобные данные соединения первого порядка кадр:

edgeDF <- rbind(edges, edges[,c(2,1)]) %>% 
      as.data.frame() %>% 
      setNames(c("NodeId", "FirstConnection")) 

edgeDF %>% arrange(NodeId, FirstConnection) 
#  NodeId FirstConnection 
# 1  Alpha  Gasoline 
# 2  Bravo    Egg 
# 3  Bravo  Hurricane 
# 4 Colonel   Felix 
# 5 Colonel   Indigo 
# 6  Demo   Felix 
# 7  Demo  Gasoline 
# 8  Demo    Jab 
# 9  Egg   Bravo 
# 10  Felix   Colonel 
# 11  Felix   Demo 
# 12  Felix  Hurricane 
# 13  Felix   Indigo 
# 14 Gasoline   Alpha 
# 15 Gasoline   Demo 
# 16 Gasoline    Jab 
# 17 Hurricane   Bravo 
# 18 Hurricane   Felix 
# 19 Indigo   Colonel 
# 20 Indigo   Felix 
# 21  Jab   Demo 
# 22  Jab  Gasoline 

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

SecondCon <- setNames(edgeDF, c("FirstConnection", "SecondConnection")) %>% 
      full_join(edgeDF) %>% filter(NodeId != SecondConnection) 

SecondCon %>% arrange(NodeId, FirstConnection, SecondConnection) 
# FirstConnection SecondConnection NodeId 
# 1   Gasoline    Demo  Alpha 
# 2   Gasoline    Jab  Alpha 
# 3  Hurricane   Felix  Bravo 
# 4   Felix    Demo Colonel 
# 5   Felix  Hurricane Colonel 
# 6   Felix   Indigo Colonel 
# 7   Indigo   Felix Colonel 
# 8   Felix   Colonel  Demo 
# 9   Felix  Hurricane  Demo 
# 10   Felix   Indigo  Demo 
# 11  Gasoline   Alpha  Demo 
# 12  Gasoline    Jab  Demo 
# 13    Jab   Gasoline  Demo 
# 14   Bravo  Hurricane  Egg 
# 15   Colonel   Indigo  Felix 
# 16   Demo   Gasoline  Felix 
# 17   Demo    Jab  Felix 
# 18  Hurricane   Bravo  Felix 
# 19   Indigo   Colonel  Felix 
# 20   Demo   Felix Gasoline 
# 21   Demo    Jab Gasoline 
# 22    Jab    Demo Gasoline 
# 23   Bravo    Egg Hurricane 
# 24   Felix   Colonel Hurricane 
# 25   Felix    Demo Hurricane 
# 26   Felix   Indigo Hurricane 
# 27   Colonel   Felix Indigo 
# 28   Felix   Colonel Indigo 
# 29   Felix    Demo Indigo 
# 30   Felix  Hurricane Indigo 
# 31   Demo   Felix  Jab 
# 32   Demo   Gasoline  Jab 
# 33  Gasoline   Alpha  Jab 
# 34  Gasoline    Demo  Jab 
+1

Это идеальный вариант и намного меньше кода, чем я думал. Спасибо за вашу помощь! –

 Смежные вопросы

  • Нет связанных вопросов^_^