Включение узлов в список ребер с исходящей степенью 0 в igraph

Я уточняю предыдущий вопрос, который задал здесь: Расчет соотношения взаимных связей для каждого узла в графике

Ответы были очень полезными, но я понял, что один из расчетов выходит неправильно. Я пытаюсь вычислить соотношение взаимных преимуществ к исходящей степени - другими словами, какой процент людей, которых я называю друзьями, назначают меня в друзья?

Когда студенты не назначают друзей (исходящая степень 0), они не включаются в мой расчет взаимных связей. Поскольку у них не может быть никаких взаимных связей, я хочу, чтобы их взаимность была рассчитана как 0. Их соотношение взаимных связей / исходящей степени также должно быть равно 0.

Вот пример:

library(igraph)    

###Creating sample edgelist###
from<- c("A", "A", "A", "B", "B", "B", "C", "D", "D", "E")
to<- c("B", "C", "D", "A", "E", "D", "A", "B", "C", "E")
weight<- c(1,2,3,2,1,3,2,2,1,1)
g2<- as.matrix(cbind(from,to, weight))

###Converting edgelist to network###
g3=graph.edgelist(g2[,1:2])
E(g3)$weight=as.numeric(g2[,3])

###Removing self-loop###
g3<-simplify(g3, remove.loops = T)

Здесь степень выхода E равна 1, а исходящая степень равна 0. Я создаю цикл для E, чтобы векторы входов и исходов оставались одинаковой длины, а затем удаляю его.

Далее я смотрю, какие номинации принимаются взаимностью:

recip<-is.mutual(g3)
recip<-as.data.frame(recip)

Затем я создаю список редактирования из g3 и добавляю recip во фрейм данных:

###Creating edgelist and adding recipe###
edgelist<- get.data.frame(g3, what = "edges")
colnames(edgelist)<- c("from", "to", "weight")

edgelist<- cbind(edgelist, recip)
edgelist

> edgelist
  from to weight recip
1    A  B      1  TRUE
2    A  C      2  TRUE
3    A  D      3 FALSE
4    B  A      2  TRUE
5    B  D      3  TRUE
6    B  E      1 FALSE
7    C  A      2  TRUE
8    D  B      2  TRUE
9    D  C      1 FALSE

Вот тут и начинаются проблемы. Поскольку E нет в from, его также нет в объектах, которые я создаю ниже.

Затем я создаю таблицу с исходящей степенью и добавляю имена вершин:

##Creating outdegree and adding vertex IDs##
outdegree<- as.data.frame(degree(g3, mode = "out"))

ID<-V(g3)$name
outdegree<-cbind(ID, outdegree)
colnames(outdegree) <- c("ID","outdegree")
rownames(outdegree)<-NULL
outdegree

Outdegree выходит именно так, как я хочу:

 ID outdegree
1  A         3
2  B         3
3  C         1
4  D         2
5  E         0

Когда я подсчитываю количество взаимных связей для каждого узла, E не включается, поскольку я использую столбец from из edgelist, о котором я говорил выше.

##Calculating number of reciprocated ties##
recip<-aggregate(recip~from,edgelist,sum)
colnames(recip)<- c("ID", "recip")
recip

> recip
  ID recip
1  A     2
2  B     2
3  C     1
4  D     1

Так вот в чем проблема. Если попытаться создать таблицу с отношением взаимных связей к исходящей степени, E не будет включено:

##Creating ratio table##
ratio<-merge(recip, outdegree, by= "ID")
ratio<-as.data.frame (recip$recip/ratio$outdegree)
ratio<- cbind(recip$ID, ratio)
colnames(ratio)<- c("ID", "ratio")
ratio

  ID     ratio
1  A 0.6666667
2  B 0.6666667
3  C 1.0000000
4  D 0.5000000

В конечном счете, мне нужна строка в ratio для E, равная 0. Поскольку соотношение здесь будет 0/0 (0 взаимных связей / 0 исходящих градусов), я, вероятно, получил бы NaN, но я могу легко преобразовать его в 0, так что было бы хорошо.

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

Есть мысли о том, как это автоматизировать?

Еще раз спасибо за помощь.

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
0
225
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

E не отображается, потому что E отсутствует в столбце from фрейма данных recip! Это только в to.

Вы можете aggregate на обоих столбцах, а затем объединить.

r1 <- aggregate(recip~from,edgelist,sum)
colnames(r1) <- c("ID", "recip")
r2 <- aggregate(recip~to,edgelist,sum)
colnames(r2) <- c("ID", "recip")
recip <- merge(r1,r2, all = T) # all = T gives the union of the df's

Который дает:

  ID recip
1  A     2
2  B     2
3  C     1
4  D     1
5  E     0

Также с пиплингом:

library(dplyr)

edgelist %>% 
    aggregate(recip~from,.,sum) %>% 
    rename(ID = from) %>% 
    merge(., edgelist %>% 
                 aggregate(recip~to,.,sum) %>% 
                 rename(ID = to), 
          all = T)

Это действительно полезно - спасибо. Я знал, что проблема возникла из-за того, что E не находится в "от", но не знал, как туда добраться.

Gary DeYoung 02.08.2018 23:22

Извините - опубликовано преждевременно, время на редактирование закончилось. А вот и остальное: решение для пиплинга сработало, как шарм. Однако у меня возник вопрос по первому. Похоже, что оба r1 и r2 объединяются "в". Это опечатка? Когда я пытаюсь закодировать r1 для агрегирования «из», он снова не учитывает E, а когда я объединяю r1 и r2, E остается вне вывода. Я обязательно воспользуюсь стратегией конвейерной обработки, но не могли бы вы рассказать мне, что не так с первой? Еще раз спасибо!

Gary DeYoung 02.08.2018 23:36

@GaryDeYoung Если этот ответ был полезен, вы должны хотя бы проголосовать за него. Если он действительно отвечает на ваш вопрос, примите его как ответ.

G5W 03.08.2018 14:21

@GaryDeYoung, да, это была опечатка! Кроме того, добавьте all = T к merge, чтобы сохранить все наблюдения как из r1, так и из r2.

paqmo 03.08.2018 15:01

@paqmo Понятно! Теперь все это имеет смысл. Кстати, только что принял ответ. Простите за опоздание.

Gary DeYoung 03.08.2018 17:45

Другие вопросы по теме