【问题标题】:FAST way to sum up neighbors' attributes in a large graph in R在 R 中的大图中总结邻居属性的快速方法
【发布时间】:2017-01-03 11:57:58
【问题描述】:

我有一个大的 igraph 对象,几乎有 1M 节点和 1.5M 边。在研究了一段时间后,我找不到对节点的邻居属性求和的过程,在这种情况下,它是二进制的。目前,我找到的最佳解决方案如下:

V(g)$sum = sapply( ego(g,1,V(g),mode = 'all',mindist = 1), function(v) sum(V(G)[v]$attr) )

但是,12 小时后它仍然嘎吱作响。

有什么建议吗?

更新 1:让我们考虑下图

library(igraph)
G <- graph.formula(1-+2,1-+3,2-+4,2-+5,3-+6,5-+7,7-+8,8-+9,9+-7, 9-+10,
               6-+9,1-+5,3-+9,10-+11,11-+12,11-+5,12-+4,4-+10,10-+4,11-+10)
V(G)$attr = c(1,1,0,0,1,0,1,0,1,0,1,0)
plot(G, vertex.label.color = "white",  edge.width=E(G)$weight, layout = layout.circle(G))

期望的结果应该是这样的......

 sapply( ego(G,1,V(G),mode = 'all',mindist = 1), function(v) sum(V(G)[v]$attr) )
 [1] 2 2 2 1 4 1 2 2 1 2 1 1

@Tamás,我尝试在不使用循环的情况下访问邻居函数,但我得到的不是上述结果...

sapply(neighbors(G,V(G)),function (v) sum(V(G)[v]$attr))
2 3 5 
1 0 1 

【问题讨论】:

    标签: r igraph sna large-data


    【解决方案1】:

    我也在使用大型网络,我在igraph要做“简单”的东西时,我有一些问题,如计算betweennesscloseness。但是,在您的情况下,我认为您可以在网络框架之外解决此问题。

    1st,将网络转换为data.frame并使用库data.table,它真的很快,用于工作大数据集来计算属性的总和。

    library(igraph)
    library(magrittr)
    library(data.table)
    
    # simple network
      g<- graph.formula(1-+2,1-+3,2-+4,2-+5,3-+6,5-+7,7-+8,8-+9,9+-7, 9-+10,
                         6-+9,1-+5,3-+9,10-+11,11-+12,11-+5,12-+4,4-+10,10-+4,11-+10)
    
      V(g)$attr = c(1,1,0,0,1,0,1,0,1,0,1,0)
    
    
    # convert the network to data.table
      dt <- as_long_data_frame(g) %>% setDT()
    
    # Calculate the sum of neighbors' attributes by origin (from). This is really fast in data.table
      mysum <- dt[, .(attr_sum = sum(to_attr)), by= from]
    
    # get the sum result back in the data doing a simple merge
      dt <- dt[mysum, on=.(from)] 
    
    # get the sum into the network object
      E(g)$attr_sum <- dt$attr_sum
    

    【讨论】:

      【解决方案2】:

      瓶颈几乎肯定是ego() 函数。尝试改用neighbors();它专门用于仅获取一阶邻居,因此速度更快 - 您也不需要在每次迭代中构造 V(g)。

      【讨论】:

      • 我用这个命令sapply(V(G), function(v) sum(neighbors(G, v, mode = 'all')$attr)),但是没有明显的提升跨度>
      • 尝试将所有顶点的属性预取到一个变量中(例如,attr &lt;- V(g)$attr),然后设置该变量的子集(即attr[neighbors(G, v, mode="all")])。不过,不确定这是否有帮助。
      【解决方案3】:

      正如@Tamás 所述,瓶颈在于ego 函数(neighbors 将产生类似的瓶颈)。对于相邻节点(即1阶邻居),可以通过使用get.adjacency拉取邻接矩阵,然后使用%*%将矩阵乘以属性向量来避免这个瓶颈:

      library(igraph)    
      set.seed(42)
      g <- erdos.renyi.game(1000000, 1500000, type = "gnm")
      V(g)$att <- as.logical(rbinom(vcount(g), 1, 0.5))
      
      system.time({
         ma  <- get.adjacency(g)
         att <- V(g)$att
         res <- as.numeric(ma %*% att)
      })
      #  user  system elapsed 
      # 0.642   0.138   0.786
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-09-16
        • 2012-03-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多