替换值时,Matrix会占用内存使用量

时间:2014-05-19 17:32:41

标签: r memory-management matrix replace

如果我替换其中的值,为什么我的矩阵的大小会翻倍?我可以阻止R这样做吗? 例如:

set.seed(42)
a <- matrix(rbinom(10000,2,0.45),ncol=10)
object.size(a)/1024/1024
# 0.038 Mb
# I want to have a mean smaller than 1 in every column
# Thus, swap 0's and 2' in every column where mean is bigger than 1
swapcol <- colMeans(a)>1
swapmat <- a[,swapcol]
tracemem(a)
# [1] "<0x7fe9d2f16f50>"
a[,swapcol][swapmat==2] <- 0
# tracemem[0x7fe9d2f16f50 -> 0x7fe9c2d98b90]: 
# tracemem[0x7fe9c2d98b90 -> 0x7fe9c2d2bf70]: 
a[,swapcol][swapmat==0] <- 2
# tracemem[0x7fe9c2d2bf70 -> 0x7fe9c2e1b460]: 
object.size(a)/1024/1024
# 0.076 Mb, memory occupation doubled

据我所知,可能会复制矩阵以替换值,但为什么它会变大? (replace()导致相同的行为)我读了Hadley关于Memory usageR Documentation这本问题的书的章节,但我仍然想知道为什么会这样。我想也许R要求操作系统有更多的空间,以防我想要放大矩阵,但为什么两倍的空间呢?这对于大型矩阵来说甚至是正确的(具有相同的因素),使我的系统交换内存(因此与潜在的节省时间的效果相矛盾)。

感谢任何提示!

2 个答案:

答案 0 :(得分:4)

问题是,02不是整数但加倍就R而言以及何时将它们分配给矩阵a的元素强制R使用双精度存储修改后的a,这会增加对象的内存大小。原始a使用整数存储,每个整数占用较少的内存。您可以通过storage.mode()

查看此信息
set.seed(42)
a <- matrix(rbinom(10000,2,0.45),ncol=10)

> storage.mode(a)
[1] "integer"

swapcol <- colMeans(a)>1
swapmat <- a[,swapcol]
a[,swapcol][swapmat==2] <- 0
a[,swapcol][swapmat==0] <- 2

> storage.mode(a)
[1] "double"
> format(object.size(a), units = "Kb")
[1] "78.3 Kb"

要解决此问题,请将L附加到您分配给a的值;这是R的整数表示法。

set.seed(42)
a <- matrix(rbinom(10000,2,0.45),ncol=10)
swapcol <- colMeans(a)>1
swapmat <- a[,swapcol]
a[,swapcol][swapmat==2] <- 0L
a[,swapcol][swapmat==0] <- 2L

> storage.mode(a)
[1] "integer"
> format(object.size(a), units = "Kb")
[1] "39.3 Kb"

答案 1 :(得分:3)

将评论转换为答案:

set.seed(42)
> a <- matrix(rbinom(10000,2,0.45),ncol=10)
> object.size(a)/1024/1024
0.0383377075195312 bytes

> swapcol <- colMeans(a)>1
> swapmat <- a[,swapcol]
> tracemem(a)
[1] "<0x7fc50ec45e00>"
> a[,swapcol][swapmat==2] <- 0L
tracemem[0x7fc50ec45e00 -> 0x7fc50d839e00]: 

> a[,swapcol][swapmat==0] <- 2L
> object.size(a)/1024/1024
0.0383377075195312 bytes

相同尺寸!