2016-08-26 28 views
3

我有一個大型的igraph對象,幾乎1M節點和1.5M的邊緣。經過一段時間的研究,我找不到一個對節點的鄰居屬性求和的過程,在這種情況下,它是一個二進制的屬性。目前,我找到的最佳解決方案如下:快速的方式來總結在一個大圖中的鄰居屬性R

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

enter image description here

和期望的結果應該是這樣的......

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 

@陶馬什,我試圖訪問鄰居的功能沒有使用循環,但取而代之的是上述結果我得到了這個...

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

回答

0

瓶頸幾乎肯定是ego()函數。請嘗試使用neighbors()代替;它專門用於獲得一階鄰居,因此速度更快 - 而且在每次迭代中都不需要構建V(g)。

+0

我用這個命令sapply(V(G),function(v)sum(neighbors(G,v,mode ='all')$ attr)),但是沒有顯着改善 – Cristobal

+0

嘗試將所有頂點的屬性預取到變量中(例如'attr < - V(g)$ attr'),然後對該變量進行子集化(即'attr [neighbors(G,v,mode =「all 「)]')。不知道這是否有幫助。 –

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 
0

正如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 

對於持家,有一個相關的答案(由我發佈)在這裏: https://stackoverflow.com/a/44726176/4300478