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