Connecting nodes by common friends

Hello

I am working with a retweets networks using igraph. My network is directed, meaning that it connects people that retweets from other users.

My format is an edgelist where arrows follow from the retweeter to the retweeted user and there are no connections among retweeters (that is, all retweeters have 0 inner degree as they don't retweet each other).

I would like to connect retweeters by common friends and simplify the network. To do so, I want to connect users by common retweeted users:

Consider the following repex:

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

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

In this case nodes A,B and E are retweeting from node C so I would like to connect all of them the following way:

plot2

Ideally, I would also have weights by the number of times they retweet from a user that I would like to incorporate to the final network but this might be another different question to tackle.

I have tried combining neighbors and intersect in a loop but my network has thousands of nodes so I need to find a cleaner way to do this is possible.

Thanks a lot in advance!

edit: I add some code I am currently trying in small toy networks but I am not sure of its performance. So far it apperas to do what I want

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)
  
}

I couldn't get your function to work. It simply errors for me.

Error in graph.data.frame(ne2, directed = F) : 
  the data frame should contain at least two columns

However, I came up with this, but its only tested on your toy and not generally.

library(igraph)
library(tidyverse)

edgelist <- read.table(text = "
                       A C
                       B C
                       D C")
par(mfcol=c(1,2))
(g <- graph.data.frame(edgelist, directed = T))
plot(g)
neighb_graph <- edgelist %>% 
  group_by(V2) %>% 
  summarise(pairs=combn(V1,2,simplify = FALSE))%>%
  pull(pairs) %>%
  unlist %>%
  as.character()

plot(make_graph(neighb_graph,directed = FALSE))
1 Like

This topic was automatically closed 21 days after the last reply. New replies are no longer allowed.

If you have a query related to it or one of the replies, start a new topic and refer back with a link.