Вот подход, объединяющий базу 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
, в той же строке.Затем остается суммировать данные путем суммирования всех соседей с разными полами.