Saya bekerja dengan jaringan retweet menggunakan igraph. Jaringan saya diarahkan, artinya menghubungkan orang-orang yang me-retweet dari pengguna lain.

Format saya adalah edgelist di mana panah mengikuti dari retweeter ke pengguna yang di-retweet dan tidak ada koneksi di antara retweeter (yaitu, semua retweeter memiliki 0 derajat dalam karena mereka tidak saling me-retweet).

Saya ingin menghubungkan retweeter dengan teman biasa dan menyederhanakan jaringan. Untuk melakukannya, saya ingin menghubungkan pengguna dengan pengguna umum yang di-retweet:

Perhatikan repetisi berikut:

edgelist <- read.table(text = "
                       A C
                       B C
                       D C")

g <- graph.data.frame(edgelist, directed = T)

Dalam hal ini node A,B dan E me-retweet dari node C jadi saya ingin menghubungkan semuanya dengan cara berikut:

result

Idealnya, saya juga akan memiliki bobot dengan berapa kali mereka me-retweet dari pengguna yang ingin saya masukkan ke jaringan akhir, tetapi ini mungkin pertanyaan lain yang berbeda untuk ditangani.

Saya telah mencoba fungsi berikut dan berfungsi di jaringan mainan kecil tetapi ketika saya mencobanya di milik saya (ribuan tepi) itu runtuh:

connect_friends<-function(edgelist){
  g <- graph.data.frame(edgelist, directed = T)
  g <- delete_vertices( g, 
                        (!V(g) %in% c(V(g)[[degree(g, mode = "in")>=2]])) & 
                          (!V(g) %in% c(V(g)[[degree(g, mode = "in")==0]])))
  el <- as.data.frame(get.edgelist(g))
  ids <- unique(c(el$V1, el$V2))
  
  y <- lapply(ids, function(id) {
    
    x <- el[which(el$V1 == id | el$V2 == id),]
    alt_nodes <- setdiff(unique(c(x$V1, x$V2)), id)
    
  })
  
  if(length(y)==0) {
    stop("No common friends found")
  }
  ne2=NULL
  ne=NULL
  for (i in 1:length(y)) {
    new_edge <- y[[i]]
    if (length(new_edge)>=2){
      ne <- t(combn(new_edge,2))
    }
    ne2 <- rbind(ne,ne2)
  }
  g2  <<-  graph.data.frame(ne2, directed  =  F)
  
}


Apakah ada cara yang lebih efisien untuk melakukannya?

Terima kasih banyak sebelumnya!

1
Luis 24 Mei 2021, 11:06

1 menjawab

Jawaban Terbaik

Memperbarui

Dengan contoh yang diperbarui, kita bisa mendapatkan

> gres
IGRAPH a824a46 UN-- 4 0 -- 
+ attr: name_1_1 (g/c), name_1_2 (g/c), name_2_1 (g/c), name_2_2 (g/c),
| loops_1_1 (g/l), loops_1_2 (g/l), loops_2_1 (g/l), loops_2_2 (g/l),
| name (v/c)
+ edges from a824a46 (vertex names):

Dan plot(gres) menunjukkan

enter image description here

Anda dapat menggunakan disjoint_union + split + make_full_graph seperti di bawah ini

gres <- do.call(
  graph.union,
  lapply(
    names(V(g))[degree(g, mode = "out") == 0],
    function(x) {
      nbs <- names(V(g))[distances(g, v = x, mode = "in") == 1]
      disjoint_union(
        set_vertex_attr(make_full_graph(length(nbs)), name = "name", value = nbs),
        set_vertex_attr(make_full_graph(1), name = "name", value = x)
      )
    }
  )
)

Yang memberikan

> gres
IGRAPH cb11da8 UN-- 4 3 -- 
+ attr: name_1 (g/c), name_2 (g/c), loops_1 (g/l), loops_2 (g/l), name
| (v/c)
+ edges from cb11da8 (vertex names):
[1] A--B A--D B--D

Dan plot(gres) menunjukkan

enter image description here

0
ThomasIsCoding 25 Mei 2021, 18:24