Rstudio的行为
Rstudio的对象浏览器修改它所判断的对象时,会在修改时强制进行复制.具体地说,对象浏览器使用至少一个R函数,在将对象的named字段的值从1重置为2的过程中,该函数的调用在内部强制对对象进行判断.从R-Internals manual人中:
当一个对象即将被更改时,将参考命名字段.值为2表示在更改对象之前必须复制该对象.[...] 值1用于情况[…]原则上,计算期间存在两份副本[…]但不再是了,所以一些基本函数可以优化,以避免在这种情况下复制.
要查看对象浏览器修改named字段(下一个代码块中为[NAM()]
),请比较运行以下行的结果.在第一种情况下,两条"线"一起运行,因此Rstudio在查询其 struct 之前没有时间"touch "X
.在第二种情况下,每一行都是单独粘贴的,因此在判断之前对X
进行了修改.
## Pasted in together
x <- 1:10; .Internal(inspect(x))
# @46b47b8 13 INTSXP g0c4 [NAM(1)] (len=10, tl=0) 1,2,3,4,5,...
## Pasted in with some delay between lines
x <- 1:10
.Internal(inspect(x))
# @42111b8 13 INTSXP g0c4 [NAM(2)] (len=10, tl=0) 1,2,3,4,5,...
一旦named字段设置为2,[<-(X, ...)
将不会修改原始对象.将以下内容一次性粘贴到Rstudio中会修改X
,而将其逐行粘贴则不会:
x <- 1:10
"[<-"(x, 1, 111)
所有这一切的另一个后果是,Rstudio的对象浏览器实际上使一些操作比其他情况下要慢.再次比较两个相同的命令,先粘贴在一起,然后一次一个:
## Pasted in together
x <- 1:5e7
system.time(x[1] <- 9L)
# user system elapsed
# 0 0 0
## Pasted in one at a time
x <- 1:5e7
system.time(x[1] <- 9L)
# user system elapsed
# 0.11 0.04 0.16
Variable behavior of [<- in R
[<-
w.r.t.修改向量X
的行为取决于X
的存储类型以及分配给它的元素的类型.这解释了R
的行为,但不是Rstudio的行为.
在R中,当[<-
附加到向量X
,或执行要求修改X
类型的子分配时,X
被复制,并且返回的值不会覆盖预先存在的变量X
.(要做到这一点,你需要做X <- "[<-(X, 2, 100)
之类的事情.
So, neither of the following modify X
X <- 1:2 ## Note: typeof(X) --> "integer"
## Subassignment that requires that X be coerced to "numeric" type
"[<-"(X, 2, 100) ## Note: typeof(100) --> "numeric"
X
# [1] 1 2
## Appending to X
"[<-"(X, 3, 100L)
X
# [1] 1 2
不过,只要有可能,R确实允许[<-
函数通过引用直接修改X
(即不制作副本).这里的"可能"包括子赋值不需要修改X
类型的情况.
So all of the following modify X
X <- c(0i, 0i, 0i, 0i)
"[<-"(X, 1, TRUE)
"[<-"(X, 2, 20L)
"[<-"(X, 3, 3.14)
"[<-"(X, 4, 5+5i)
X
# [1] 1.00+0i 20.00+0i 3.14+0i 5.00+5i