如果我替换其中的值,为什么我的矩阵的大小会翻倍?我可以阻止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 usage和R Documentation这本问题的书的章节,但我仍然想知道为什么会这样。我想也许R要求操作系统有更多的空间,以防我想要放大矩阵,但为什么两倍的空间呢?这对于大型矩阵来说甚至是正确的(具有相同的因素),使我的系统交换内存(因此与潜在的节省时间的效果相矛盾)。
感谢任何提示!
答案 0 :(得分:4)
问题是,0
,2
等不是整数但加倍就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
相同尺寸!