Я не совсем эксперт по сетевому анализу, и igraph
в частности. Но я думаю, что что-то подобное может быть полезным.
Я изменил часть вашего анализа перед обработкой, потому что нашел несколько сложностей:
- Кодировка венгерского языка: Потребовалось время, чтобы найти правильную кодировку (см.
locale = 'cp1250
в read_csv
вызове; - После сбора я изменил
org_name*
на org
и org*
на type
; - Я использую
chop
, чтобы упростить spread
-> unnest
; - Я пытался сделать
filter
вызов короче, но без особого успеха; - Я использую
stringr::str_to_title()
, чтобы объединить org
var, потому что есть такие же имена, которые отличаются только тем, что n-е слово в заглавных буквах или нет; Я использую coalesce
для заполните NA
s org
var значениями от type
var.
library(tidyverse)
library(magrittr)
library(igraph)
jobbik <- read_csv(
"http://eborbath.github.io/stackoverflow/jobbik.csv",
trim_ws = T,
locale = locale(encoding = 'cp1250')
)
jobbik %<>%
gather('key', 'val', -c('id', 'date')) %>%
mutate(
key = case_when(
grepl('^org_names\\d+$', key) ~ 'org',
grepl('^org\\d+$', key) ~ 'type',
TRUE ~ key
)
) %>%
chop(val) %>%
spread(key, val) %>%
unnest(c(org, type)) %>%
filter(
!(is.na(org) & (type == 'no other organizer')) &
!((is.na(org) | grepl('.*jobbik.*', org, T )) & (type == 'JOBBIK'))
) %>%
mutate(org = str_to_title(coalesce(org, type)))
Чтобы сформировать фрейм данных ребер графа, я группирую по id
из событие, отфильтровывая все события, которые поддерживаются только одной организацией (поэтому нет связи с другими организациями), и, наконец, я создаю p в пределах id
между организациями с функцией combn
. В результате получается символьный вектор Org A-Org B
, который после разнесения я разделяю на столбцы from
и to
, используя -
в качестве разбиения (что потенциально опасно, если имя организации имеет -
символ в нем). Я также отфильтровываю все самопетли, если они есть. Последняя операция - count
, чтобы вычислить, как часто каждая отдельная пара появляется в списке встреч Jobbik. Я присваиваю его width
, потому что при построении графика igraph::plot
будет использовать его как ширину для ребер.
ed <- jobbik %>%
group_by(id) %>%
filter(n() > 1) %>%
summarise(edge = list(combn(org, 2, paste, collapse = '-'))) %>%
unnest(edge) %>%
separate(edge, into = c('from', 'to'), sep = '-') %>%
filter(from != to) %>%
count(from, to, name = width)
Аналогичный анализ выполняется для вершин. Я добавляю сюда дополнительную информацию для вершин, а именно: событие id
, date
, организацию type
, которую вы можете использовать в дальнейшем, color
- отображение количества раз, данное орг. поддерживается Jobbik и некоторые дополнительные графические параметры для последнего сюжета.
nd <- jobbik %>%
filter(org %in% c(ed$from, ed$to)) %>%
group_by(name = org) %>%
summarise(
id = sprintf('Event ids: %s', paste(id, collapse = ', ')),
date = sprintf('Event dates: %s', paste(date, collapse = ', ')),
type = sprintf('Org. type: %s', paste(type, collapse = '; ')),
color = n()
) %>%
ungroup() %>%
mutate(
color = heat.colors(10)[cut(color, 10)],
frame.color = NA,
label.dist = 1,
label.cex = .5,
label.color = 'gray10'
)
С помощью этих данных мы можем создать неориентированный граф, используя функцию graph_from_data_frame()
:
g <- graph_from_data_frame(ed, F, nd)
vertex_attr(g, 'size') <- degree(g, mode = 'all')
Во второй строке выше я добавляю атрибут вершины size
для отображения степени вершины к размеру вершин.
И, наконец, для построения сообщества, я могу сделать просто:
plot(
g,
edge.curved = .2,
layout = layout_with_kk,
asp = 1,
main = 'Jobbik interaction network',
)
![Jobbik](https://i.stack.imgur.com/DggCB.png)