通过 R 中的普通朋友连接节点

Connecting nodes by common friends in R

我正在使用 igraph 处理转推网络。我的网络是定向的,这意味着它将转发其他用户推文的人联系起来。

我的格式是一个边缘列表,其中箭头从转发者到转发用户,并且转发者之间没有连接(也就是说,所有转发者的内度为 0,因为他们不互相转发)。

我想连接普通朋友的转发器,简化网络。为此,我想通过转发的普通用户联系用户:

考虑以下 repex:

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

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

在这种情况下,节点 A、B 和 E 正在从节点 C 转发,所以我想通过以下方式连接所有这些节点:

理想情况下,我还会根据用户转发推文的次数来加权,我想将其合并到最终网络中,但这可能是另一个需要解决的不同问题。

我尝试了以下功能,它在小型玩具网络中确实有效,但是当我在我的(数千个边缘)中尝试它时,它崩溃了:

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


有没有更有效的方法?

非常感谢!

更新

通过更新的例子,我们可以得到

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

plot(gres)显示

您可以像下面这样使用 disjoint_union + split + make_full_graph

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

这给出了

> 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

plot(gres)显示