使用 cbind 分配 R 内存
R memory allocation with cbind
我正在采用大型(密集)网络矩阵并将其转换为边缘列表。然而,当我这样做时,在 R 中分配的内存似乎很疯狂。在我的例子中,我有一个 12MB 的矩阵 (1259 x 1259),当转换为边缘列表 (i, j, w) 时,它占用了 71MB 的内存!我正在使用 igraph 包来执行操作,但我认为它与此无关。
这是我正在处理的数据。
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(上周刚刚安装)。
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
我正在采用大型(密集)网络矩阵并将其转换为边缘列表。然而,当我这样做时,在 R 中分配的内存似乎很疯狂。在我的例子中,我有一个 12MB 的矩阵 (1259 x 1259),当转换为边缘列表 (i, j, w) 时,它占用了 71MB 的内存!我正在使用 igraph 包来执行操作,但我认为它与此无关。 这是我正在处理的数据。
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(上周刚刚安装)。
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