Ответ 1
поведение Rstudio
Rstudio-объект-браузер изменяет объекты, которые он анализирует, таким образом, чтобы принудительное копирование было изменено. В частности, в обозревателе объектов используется по меньшей мере одна функция R, вызов которой внутренне принудительно оценивает объект, в процессе сброса значения поля объекта с именем от 1 до 2. Из Руководство по R-Internals:
Когда объект должен быть изменен, проконсультируется имя с именем. Значение 2 означает, что объект должен быть дублирован перед изменением. [...] Значение 1 используется для ситуаций [...], где в принципе две копии a существуют в течение всего времени вычисления [...], но уже нет, и поэтому некоторые примитивные функции могут быть оптимизированы чтобы избежать копирования в этом случае.
Чтобы увидеть, что браузер объектов изменяет поле с именем ([NAM()]
в следующем блоке кода), сравните результаты выполнения следующих строк. В первом случае обе "линии" запускаются вместе, так что Rstudio не успевает "коснуться" 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
Измененное поведение [< - in R
Поведение [<-
w.r.t. изменение вектора X
зависит от типов хранения X
и элемента, назначаемого ему. Это объясняет поведение R
, но не Rstudio.
В R, когда [<-
либо добавляется к вектору X
, либо выполняет переназначение, требующее модификации типа X
, копируется X
, а возвращаемое значение не перезаписывает пре- существующая переменная X
. (Для этого вам нужно сделать что-то вроде X <- "[<-(X, 2, 100)
.
Итак, ни одно из следующих изменений 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
.
Итак, все следующие изменения 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