Ответ 1
Мэтью Доулл задал тот же вопрос здесь, и Питер Далгаард ответил так:
Это сложный бизнес... Я не совсем уверен, что все будет правильно, но попробуйте
Когда вы назначаете константу, присваиваемое вами значение уже часть выражения присваивания, поэтому, если вы хотите его изменить, вы должны дублироваться. Таким образом,
NAMED==2
onz <- 1
в основном предотвращает вас случайно "изменяя значение 1". Если бы это было не так, укусить код вродеfor(i in 1:2) {z <- 1; if(i==1) z[1] <- 2}
.
Это может показаться экзотическим, но на самом деле логическое обоснование точно такое же, как для приращения NAM
to 2
при выполнении присвоения формы x <- y
.
Как обсуждалось здесь, R поддерживает иллюзию "вызвать по значению", чтобы избежать по крайней мере некоторого ненужного копирования объектов. Так, например, x <- y
действительно просто привязывает значение символа x
к y
. Однако опасность сделать это без дополнительных мер предосторожности заключается в том, что последующая модификация x
также изменит y
и любые другие символы, связанные с y
. R обходит это, отмечая значение y
как "связанное с" (путем установки его NAM=2
), как только он назначен (или даже потенциально назначен) другому символу.
Когда вы выполняете x <- 1
, 1
является более или менее просто другим y
, значение которого привязывается к символу x
выражением присваивания. Просто из-за того, что потенциальная опасность, связанная с последующей модификацией значения x
(напомню, что на данный момент это просто ссылка на значение 1
!), Ужасно представить. Но, как всегда, с присвоениями одного символа другому, R устанавливает NAM=2
, и никакие изменения без фактического копирования не допускаются.
Причина x <- 1:10
отличается (например, x <- 1:1
, x <- c(1)
, x <- seq(1)
и даже x <- -1
)), что RHS является фактически вызовом функции, и результатом этого вызова функции является то, что присваивается x
. В этих случаях значение x
является не только ссылкой на значение какого-либо другого символа; изменение x
не приведет к изменению значения какого-либо другого символа, поэтому нет необходимости устанавливать NAM=2
.