Menyertakan node dalam daftar tepi dengan derajat keluar 0 di igraph

Saya menindaklanjuti pertanyaan sebelumnya yang saya tanyakan di sini: Menghitung rasio ikatan timbal balik untuk setiap node di igraph

Jawabannya sangat membantu, tetapi saya menyadari salah satu perhitungannya tidak tepat. Saya mencoba mencari tahu rasio sisi timbal balik terhadap derajat keluar--dengan kata lain, berapa persentase orang yang saya nominasikan sebagai teman menominasikan saya sebagai teman?

Ketika siswa tidak mencalonkan teman (derajat keluarnya 0), mereka tidak termasuk dalam perhitungan ikatan timbal balik saya. Karena mereka tidak dapat memiliki ikatan timbal balik, saya ingin timbal baliknya dihitung sebagai 0. Rasio ikatan timbal balik/derajat keluarnya juga harus 0.

Berikut ini contohnya:

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)

Di sini, derajat masuk E adalah 1 dan derajat keluar adalah 0. Saya membuat loop mandiri untuk E sehingga vektor derajat masuk dan keluar tetap sama panjangnya, lalu menghapusnya.

Selanjutnya, saya melihat nominasi mana yang dibalas:

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

Lalu saya membuat edgelist dari g3, dan menambahkan recip ke bingkai data:

###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

Di sinilah masalahnya dimulai. Karena E tidak ada di from, maka E juga tidak ada di objek yang saya buat di bawah ini.

Selanjutnya, saya membuat tabel dengan derajat keluar dan menambahkan nama titik:

##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 keluar sesuai keinginan saya:

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

Saat saya menghitung jumlah ikatan timbal balik untuk setiap node, E tidak disertakan, karena saya menggunakan kolom from dari edgelist yang saya bahas di atas.

##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

Jadi di situlah masalahnya. Jika mencoba membuat tabel dengan rasio ikatan timbal balik terhadap derajat keluar, E tidak termasuk:

##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

Pada akhirnya, saya ingin baris di ratio untuk E yang sama dengan 0. Karena rasio di sini adalah 0/0 (0 ikatan timbal balik/0 derajat keluar), saya mungkin akan mendapatkan NaN tetapi saya dapat mengubahnya menjadi 0 dengan mudah, sehingga akan baik-baik saja.

Saya dapat menyiasatinya dan mengekspor data ke Excel, menjalankan penghitungan dengan tangan, dan membuatnya tetap mudah. Tapi itu tidak akan membantu meningkatkan keterampilan pengkodean saya, dan saya memiliki banyak jaringan yang harus dijalankan, jadi ini juga sangat tidak efisien.

Adakah pemikiran tentang cara mengotomatiskan ini?

Sekali lagi terima kasih atas bantuan Anda.


person Gary DeYoung    schedule 02.08.2018    source sumber


Jawaban (1)


E tidak muncul karena E tidak ada di kolom from pada bingkai data recip! Hanya di to.

Anda dapat aggregate di kedua kolom lalu menggabungkannya.

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

Yang memberikan:

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

Juga, dengan pemipaan:

library(dplyr)

edgelist %>% 
    aggregate(recip~from,.,sum) %>% 
    rename(ID = from) %>% 
    merge(., edgelist %>% 
                 aggregate(recip~to,.,sum) %>% 
                 rename(ID = to), 
          all = T)
person paqmo    schedule 02.08.2018
comment
Ini sangat membantu--terima kasih. Saya tahu masalahnya karena E tidak masuk, tetapi tidak yakin bagaimana menuju ke sana. - person Gary DeYoung; 03.08.2018
comment
Maaf--diposting sebelum waktunya, dan kehabisan waktu untuk mengedit. Berikut sisanya: Solusi piplining bekerja dengan sangat baik. Tapi saya punya pertanyaan tentang yang pertama. Sepertinya r1 dan r2 keduanya digabungkan. Apakah ini salah ketik? Ketika saya mencoba mengkodekan r1 untuk mengagregasinya lagi-lagi meninggalkan E, dan ketika saya menggabungkan r1 dan r2, E tidak dimasukkan dalam output. Saya pasti akan menggunakan strategi pipelining, tapi bisakah Anda memberi tahu saya apa yang salah dengan strategi pertama? Terima kasih lagi! - person Gary DeYoung; 03.08.2018
comment
@GaryDeYoung Jika jawaban ini bermanfaat, Anda setidaknya harus memberi suara positif. Jika itu benar-benar menjawab pertanyaan Anda, terimalah itu sebagai jawabannya. - person G5W; 03.08.2018
comment
@GaryDeYoung ya, itu salah ketik! Tambahkan juga all = T ke merge untuk memastikan bahwa semua pengamatan dari r1 dan r2 disimpan. - person paqmo; 03.08.2018
comment
@paqmo Mengerti! Ini semua masuk akal sekarang. Ngomong-ngomong, baru saja menerima jawabannya. Mohon maaf atas keterlambatannya. - person Gary DeYoung; 03.08.2018