是否在R中切片复制修改?

问题描述 投票:1回答:3

here提到R在将变量赋给新变量时使用copy-on-modify,包括将参数传递给函数。

然而,切片(vectorlistdata frame)是否创建了一个相同类型的新对象,其中包含原始对象子集的oopies,或者是新元素中的元素存储原始对象的副本或仅仅是复制修改参考?

r slice copy-on-write
3个回答
2
投票

这是一个复杂的话题。你应该先阅读有关NAMED mechanism的内容。

如果运行以下命令,则会看到列表元素没有副本(因为列表基本上是指向其元素的指针):

> a <- list(1, 2, 3, 4, 5)
> 
> b <- a[1:2]
> .Internal(inspect(b)) 
@0x000000001327e5b8 19 VECSXP g0c2 [NAM(3)] (len=2, tl=0)
  @0x00000000136f6b60 14 REALSXP g0c1 [NAM(3)] (len=1, tl=0) 1
  @0x00000000136f6b28 14 REALSXP g0c1 [NAM(3)] (len=1, tl=0) 2
> 
> 
> c <- a[1:2]
> .Internal(inspect(c)) 
@0x000000001327e678 19 VECSXP g0c2 [NAM(3)] (len=2, tl=0)
  @0x00000000136f6b60 14 REALSXP g0c1 [NAM(3)] (len=1, tl=0) 1
  @0x00000000136f6b28 14 REALSXP g0c1 [NAM(3)] (len=1, tl=0) 2
> 
> b[1] <- 6
> .Internal(inspect(b)) 
@0x000000001327e6f8 19 VECSXP g0c2 [NAM(1)] (len=2, tl=0)
  @0x0000000013745b58 14 REALSXP g0c1 [] (len=1, tl=0) 6
  @0x00000000136f6b28 14 REALSXP g0c1 [NAM(3)] (len=1, tl=0) 2
> 
> .Internal(inspect(c))
@0x000000001327e678 19 VECSXP g0c2 [NAM(3)] (len=2, tl=0)
  @0x00000000136f6b60 14 REALSXP g0c1 [NAM(3)] (len=1, tl=0) 1
  @0x00000000136f6b28 14 REALSXP g0c1 [NAM(3)] (len=1, tl=0) 2

如果您是子集向量,则会有所不同。

您可能也对new reference counting mechanism感兴趣。


1
投票

将原子矢量子集设置为较短的原子矢量将为您提供一个新的矢量。从对象中对整个向量进行子集化可以为您提供复制修改引用。这样做的结果是你可以通过子集来获取一个新的更短的列表对象,但它的内容将是对原始内容的引用(没有总体内存成本),直到你修改为止。

有关更多详细信息,请参阅有关内存管理的Hadley's notes


0
投票

python不同,R可以在任何时候创建新对象。例如:

> a=c(1,2,3,4,5)
> a
[1] 1 2 3 4 5
> b=a[1]
> b
[1] 1
> b=7
> b
[1] 7
> a
[1] 1 2 3 4 5

对于vectorslistsdataframes,这同样适用。看看thisR帖子中的参考对象。

© www.soinside.com 2019 - 2024. All rights reserved.