igraph смежные края на основе атрибутов - PullRequest
0 голосов
/ 01 декабря 2018

Для каждой вершины меня интересует количество смежных ребер в зависимости от условия.В следующем примере условие имеет другой пол.

Пример:

library(igraph)
library(ggraph)
library(tidyverse)


nodes <- tibble(id = 1:4, 
                gender = c("M", "F", "F", "M"), 
                names = c("Bob", "Allie", "Mary", "Johnathon"))

edges <- tibble(from = c(1, 3, 2, 4, 1, 2, 1, 4),
                to = c(2, 2, 4, 1, 3, 1, 4, 3))

network <- graph_from_data_frame(d = edges, vertices = nodes, directed = TRUE)

ggraph(network) + 
geom_edge_link(arrow = arrow(length = unit(4, 
'mm')), 
         start_cap = circle(4, 'mm'), 
         end_cap = circle(4, 'mm')) + 
geom_node_text(aes(label = names)) +
theme_graph()

Example Plot

Желаемый результат:

id  name          adjacent_edges

1    Bob          1
2    Allie        1
3    Mary         2
4    Johnathon    1

1 Ответ

0 голосов
/ 01 декабря 2018

Вот подход, объединяющий базу R с igraph:

nodes %>% 
  mutate(adjacent_edges = colSums(as.matrix(outer(gender, gender, `!=`) * as_adj(network)) != 0))
# A tibble: 4 x 4
#      id gender names     adjacent_edges
#   <int> <chr>  <chr>              <dbl>
# 1     1 M      Bob                    1
# 2     2 F      Allie                  1
# 3     3 F      Mary                   2
# 4     4 M      Johnathon              1

Здесь

outer(gender, gender, `!=`)

строит матрицу с TRUE записями, когда гендеры разные, тогда как as_adj(network))обычная матрица смежности графовТогда их продукт будет иметь ненулевые записи именно тогда, когда мы хотим - в случае связанных узлов с разными полами.Суммирование по таким случаям дает желаемый результат.

Вот еще один, более длинный, но и более прозрачный:

edges %>% full_join(nodes, by = c("from" = "id")) %>% 
  full_join(nodes, by = c("to" = "id"), suff = c(".from", ".to")) %>%
  group_by(to, names.to) %>% summarise(adjacent_edges = sum(gender.to != gender.from)) %>%
  rename(id = to, name = names.to)
# A tibble: 4 x 3
# Groups:   id [4]
#      id name      adjacent_edges
#   <dbl> <chr>              <int>
# 1     1 Bob                    1
# 2     2 Allie                  1
# 3     3 Mary                   2
# 4     4 Johnathon              1

В этом случае мы начнем со списка ребер и дважды добавим списокузлы: один раз, чтобы иметь информацию об узле о ребре from, и один раз, чтобы иметь информацию об узле о ребре to, в той же строке.Затем остается суммировать данные путем суммирования всех соседей с разными полами.

...