R 替换值时,矩阵将内存使用率提高一倍

R 替换值时,矩阵将内存使用率提高一倍,r,memory-management,matrix,replace,R,Memory Management,Matrix,Replace,如果替换矩阵中的值,为什么矩阵的大小会加倍?我可以阻止R这样做吗? 例如: set.seed(42) 0x7fe9c2d2bf70]: a[,swapcol][swapmat==0]0x7fe9c2e1b460]: 对象。大小(a)/1024/1024 #0.076MB,内存占用翻倍 我知道矩阵可能会被复制以替换值,但为什么它会变大?(replace()导致了同样的行为)我读了哈德利的书中关于这个问题的章节,以及这个问题的答案,但我仍然想知道为什么会发生这种情况。我想也许R需要更多的操作系统空

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

set.seed(42)
0x7fe9c2d2bf70]:
a[,swapcol][swapmat==0]0x7fe9c2e1b460]:
对象。大小(a)/1024/1024
#0.076MB,内存占用翻倍
我知道矩阵可能会被复制以替换值,但为什么它会变大?(replace()导致了同样的行为)我读了哈德利的书中关于这个问题的章节,以及这个问题的答案,但我仍然想知道为什么会发生这种情况。我想也许R需要更多的操作系统空间,以防我想放大矩阵,但是为什么要增加两倍的空间呢?对于大型矩阵,这甚至是正确的(使用相同的因子),这使得我的系统交换内存(从而与潜在的节省时间效果相矛盾)


谢谢你的提示

将评论转换为答案:

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
set.seed(42)
>a对象。大小(a)/1024/1024
0.0383377075195312字节
>swapcol 1
>swapmat轨迹图(a)
[1] ""
>a[,swapcol][swapmat==2]0x7fc50d839e00]:
>a[,swapcol][swapmat==0]对象。大小(a)/1024/1024
0.0383377075195312字节

同样大小

将评论转换为答案:

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
set.seed(42)
>a对象。大小(a)/1024/1024
0.0383377075195312字节
>swapcol 1
>swapmat轨迹图(a)
[1] ""
>a[,swapcol][swapmat==2]0x7fc50d839e00]:
>a[,swapcol][swapmat==0]对象。大小(a)/1024/1024
0.0383377075195312字节

同样大小

问题在于
0
2
等对于R而言不是整数而是双倍数,当您将它们分配给矩阵
a
的元素时,您强制R使用双倍数存储修改后的
a
,这会增加对象的内存大小。原始
a
使用整数存储,每个整数占用的内存更少。您可以通过
storage.mode()
看到这一点:


问题在于,
0
2
等对于R而言不是整数而是双倍数,当您将它们分配给矩阵
a
的元素时,您强制R使用双倍数存储修改后的
a
,这会增加对象的内存大小。原始
a
使用整数存储,每个整数占用的内存更少。您可以通过
storage.mode()
看到这一点:


0
2
是浮动(即双倍)。你的矩阵包含整数。使用
0L
2L
强制R将它们视为整数。谢谢!成功了。然而有点出乎意料。。。我还有很多东西要学。如果你用一个非常简短的答案来表述它,我会接受它。你也可能对
typeof()
感兴趣,比如
typeof(swapmat)
typeof(4);类型(4L);typeof(1:4)
等@GavinSimpson——是的。在我看到你的答案之前就发布了。看到这两个并排的对象(并再次思考它们之间的区别)确实激发了我前段时间的重温。@Andarin R必须假设一些关于值的东西,因为我们在创建对象时不在R中键入对象,这与其他一些语言不同。惯例是假设双倍,这可能是因为对于统计而言,可能需要在各种例程中对数据进行双倍计算。
0
2
是浮动(即双倍)。你的矩阵包含整数。使用
0L
2L
强制R将它们视为整数。谢谢!成功了。然而有点出乎意料。。。我还有很多东西要学。如果你用一个非常简短的答案来表述它,我会接受它。你也可能对
typeof()
感兴趣,比如
typeof(swapmat)
typeof(4);类型(4L);typeof(1:4)
等@GavinSimpson——是的。在我看到你的答案之前就发布了。看到这两个并排的对象(并再次思考它们之间的区别)确实激发了我前段时间的重温。@Andarin R必须假设一些关于值的东西,因为我们在创建对象时不在R中键入对象,这与其他一些语言不同。惯例是假设双倍,可能是因为对于统计而言,可能需要在各种例程中进行数据双倍的计算。感谢您提供了非常详细的答案!(关于
格式(object.size)
..的提示)我认为它的行为更像C,只有在必要时才转换为
double
(2是
int
),尽管我认为R将一切都视为
double
。然而,我的二项式矩阵被创建为
int
,而不是一个基本
int
s的向量,这让我感到惊讶(例如
typeof(rbinom(3,1,1))
vs
typeof(rep(1,3))
),谢谢你详细的回答!(关于
格式(object.size)
..的提示)我认为它的行为更像C,只有在必要时才转换为
double
(2是
int
),尽管我认为R将一切都视为
double
。然而,我的二项式矩阵被创建为
int
,而不是一个基本
int
s的向量,这让我感到惊讶(例如
typeof(rbinom(3,1,1))
vs
typeof(rep(1,3))
)。
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"
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"