Как создать сеть Igraph из фрейма данных, где ребра равны значениям нескольких строк?

#r #igraph

#r #igraph

Вопрос:

Я пытаюсь применить анализ социальных сетей к привычкам голосования в Конгрессе и испытываю трудности с созданием своей сети. У меня есть data.frame из 100 сенаторов и то, как они спонсировали 20 законопроектов (где значение представляет разные степени спонсорства). Упрощенная версия выглядит следующим образом:

< d

   X AkakaDanielK AlexanderLamar AllardWayne BarrassoJohn
1 B1            0              2           1            2
2 B2            0              0           0            0
3 B3            0              0           0            0
4 B4            0              0           0            0
5 B5            0              0           0            0
6 B6            0              0           0            0
  

Я не могу понять, как сделать столбцы вершинами, а ребра — общим спонсорством счета. Любая помощь была бы оценена.

Ответ №1:

Для выполнения этой задачи вам необходимо преобразовать матрицу. Здесь я просто реплицирую ваши данные без правильных имен и добавляю несколько ребер (в противном случае вы получите только одного сенатора, подключенного к нему или к себе несколько раз):

 set.seed(1)
m <- matrix(0, nrow = 6, ncol = 4)
colnames(m) <- letters[1:4]
rownames(m) <- 1:6
m[] <- sample(0:2, 24, replace = T, prob = c(.5,.3,.2))
  

Используя igraph подход, вы можете использовать функцию graph_from_incidence_matrix , которая приводит к двухрежимному графику как сенаторов, так и законопроектов в качестве вершин:

 g <- graph_from_incidence_matrix(m, directed = F, multiple = T)
  

а затем преобразовать график в одномодовую проекцию, состоящую исключительно из сенаторов, связанных через законопроекты, которые они совместно используют:

 g_sponsors <- bipartite.projection(g, multiplicity = T)[[2]]
  

Другой менее типоемкий способ — использовать базу R для преобразования матрицы, а затем считывать ее как матрицу смежности:

 m_sponsors <- t(m) %*% m
g_sponsors <- graph_from_adjacency_matrix(m_sponsors, weighted = T)
  

Я надеюсь, что это поможет!

Комментарии:

1. Это сработало хорошо. На этой ноте, если бы я хотел сеть только из сенаторов с большим количеством подключений, где она сохраняет ребра только между сенаторами, когда количество законопроектов, которые они спонсировали, находится в верхнем квартиле, разделил бы я фрейм данных перед превращением его в сеть, или есть способ сделать это после создания сети?

2. Вы можете сделать и то, и другое. Существует delete.edges функция (2), которая удаляет определенные ребра, или вы можете установить значения в матрице (1): m_sponsors[m_sponsors <= quantile(E(g_sponsors)$weight, .75)] <- 0 или (2): g_top <- delete.edges(g_sponsors, which(E(g_sponsors)$weight >= quantile(E(g_sponsors)$weight, .75)))