Мы можем сделать это, используя tidyverse
.
group_split
с аргументом keep = FALSE
разбивает фрейм данных по столбцу to
на список фреймов, одновременно удаляя переменную группировки из выходных данных.
map_dfr
расширяет каждый фрейм данных, находя все комбинации from
и самого себя (например, expand.grid
)._dfr
означает, что список вывода будет привязан к строке для формирования кадра данных.
pmap_dfr
работает с каждой строкой кадра данных и сортируется по горизонтали (sort(c(...))
).set_names
необходимо для выравнивания столбцов после сортировки.tibble(!!!
объединяет отсортированный вектор в строку tibble
, эффективно превращая его в вектор-строку.
filter
и distinct
удаляет петли и дублирующиеся ссылки
Обратите внимание, что и group_split
, и group_map
в настоящее время являются экспериментальными функциями.Пожалуйста, используйте с осторожностью.
library(tidyverse)
net1 %>%
group_by(to) %>%
group_split(keep = FALSE) %>%
map_dfr(expand, crossing(from, to = from)) %>%
pmap_dfr(~ tibble(!!!sort(c(...)) %>% set_names(c("from", "to")))) %>%
filter(from != to) %>%
distinct()
или с group_map
:
net1 %>%
group_by(temp = to) %>%
group_map(~ expand(.x, crossing(from, to = from))) %>%
ungroup() %>%
select(-temp) %>%
pmap_dfr(~ tibble(!!!sort(c(...)) %>% set_names(c("from", "to")))) %>%
filter(from != to) %>%
distinct()
или с inner_join
:
net1 %>%
inner_join(net1, by = "to") %>%
select(from = from.x, to = from.y) %>%
pmap_dfr(~ tibble(!!!sort(c(...)) %>% set_names(c("from", "to")))) %>%
filter(from != to) %>%
distinct()
Мы также можем использовать graph_from_data_frame
вместо pmap_dfr
для возврата неориентированного графика (обязательно загрузите igraph
до загрузки tidyverse
, в противном случае вы можете получить неожиданные ошибки):
library(igraph)
library(tidyverse)
net1 %>%
inner_join(net1, by = "to") %>%
select(from = from.x, to = from.y) %>%
igraph::graph_from_data_frame(directed = FALSE) %>%
igraph::as_data_frame(what = "edges") %>%
filter(from != to) %>%
distinct()
Вывод:
# A tibble: 4 x 2
from to
<chr> <chr>
1 Person_1 Person_2
2 Person_3 Person_4
3 Person_3 Person_5
4 Person_4 Person_5
Данные:
net1 <- structure(list(from = c("Person_1", "Person_2", "Person_3", "Person_4",
"Person_5", "Person_6"), to = c("Event1", "Event1", "Event2",
"Event2", "Event2", "Event3")), class = "data.frame", row.names = c(NA,
-6L))