2017-04-18 40 views
1

我正在採取一個大(密集)網絡矩陣並將其轉換爲邊界列表。然而,當我這樣做時,R中分配的內存似乎很瘋狂。在我的情況下,我有一個12MB的矩陣(1259 x 1259),當轉換爲edgelist(i,j,w)時,佔用了71MB的內存!我使用igraph軟件包來執行操作,但我認爲它與此無關。 這是我正在做的數據。Rb內存分配與cbind

library(igraph) 
A <- matrix(runif(25), 5, 5) 
A <- A %*% t(A) 
diag(A) <- 0 

我做了對稱矩陣和對角線0,因爲這是我的數據看起來像,但我不認爲它很重要的這個問題。 這裏我用的igraph:

# using igraph here 
adj <- graph.adjacency(as.matrix(A),weighted=TRUE) 
object.size(A) # 400 bytes 
object.size(adj) # 2336 bytes 

我得到了IGRAPH ADJ對象將更大。這不是問題。

el <- get.edgelist(adj) 
class(el) # "matrix" 
object.size(el) # 520 bytes 

w <- E(adj)$weight 
class(w) # "numeric" 
object.size(w) # 200 bytes 

# expect something ~720 bytes 
adj_w <- cbind(el,w) 
class(adj_w) # "matrix" 
object.size(adj_w) # 1016 bytes 

爲什麼adj_w上的記憶體這麼大?它甚至不是線性的,因爲在這裏,原始到最終是400字節到1016字節,但在我的(更大的)數據中是12MB到71MB。

僅供參考:我在Macbook Pro上本地使用最新版本的RStudio(上週安裝了它)。

回答

3

adj_w較大,因爲cbind添加了一個列名。刪除它,你又回到了正確的尺寸。

head(adj_w) 
#     w 
# [1,] 1 2 1.189969 
# [2,] 1 3 1.100843 
# [3,] 1 4 0.805436 
# [4,] 1 5 1.001632 
# [5,] 2 1 1.189969 
# [6,] 2 3 1.265916 

object.size(adj_w) 
# 1016 bytes 

attributes(adj_w) 
# $dim 
# [1] 20 3 
# 
# $dimnames 
# $dimnames[[1]] 
# NULL 
# 
# $dimnames[[2]] 
# [1] "" "" "w" 
# 
# 

adj_w2 <- adj_w 
dimnames(adj_w2) <- NULL 
object.size(adj_w2) 
# 680 bytes 

爲了避免自動列名此外,您可以將矢量轉換到一個矩陣...

adj_w3 <- cbind(el, matrix(w)) 
object.size(adj_w3) 
# 680 bytes 

...,或者在deparse.level = 0參數傳遞給cbind

adj_w4 <- cbind(el, w, deparse.level = 0) 
object.size(adj_w4) 
# 680 bytes 
+0

您回答了技術部分。我也在做一個不合邏輯的假設。在我看來,A和adj_w代表相同的網絡,因此應該是相同的大小,但A是400 b和adj_w(即使進行調整)是680 b。爲什麼這麼大?我犯的錯誤是現在索引必須被存儲。在A中,每個1:N維都是隱含的,而不是存儲的,但是現在,adj_w的前兩列存儲這些索引,這些索引幾乎是存儲大小的三倍。 –