Подтвердить что ты не робот

Почему сначала один вектор длиной в NAM (2)?

Я наткнулся на это поведение:

x <- 1:5
> tracemem(x)
[1] "<0x12145b7a8>"
> "names<-"(x, letters[1:5])
a b c d e 
1 2 3 4 5 
> x
a b c d e 
1 2 3 4 5  
> y <- 1L
> tracemem(y)
[1] "<0x12587ed68>"
> "names<-"(y,letters[1])
tracemem[0x12587ed68 -> 0x12587efa8]: 
a 
1
> y
[1] 1 

при попытке помочь кому-то выяснить почему в первом случае имена векторов изменяются, но в последнем они не являются.

Ясно, что копируется длина одного вектора, а вектор длины 5 изменяется на месте:

> x <- 1:5
> y <- 1L
> .Internal(inspect(x))
@121467490 13 INTSXP g0c3 [MARK,NAM(1)] (len=5, tl=0) 1,2,3,4,5
> .Internal(inspect(y))
@1258d74d8 13 INTSXP g0c1 [NAM(2)] (len=1, tl=0) 1

Почему длина одного вектора начинается с его свойства NAMED, увеличенного до 2?

В ответ на комментарий @nograpes ниже, я вижу это на OS X 10.7.5 и R 3.0.2.

4b9b3361

Ответ 1

Мэтью Доулл задал тот же вопрос здесь, и Питер Далгаард ответил так:

Это сложный бизнес... Я не совсем уверен, что все будет правильно, но попробуйте

Когда вы назначаете константу, присваиваемое вами значение уже часть выражения присваивания, поэтому, если вы хотите его изменить, вы должны дублироваться. Таким образом, NAMED==2 on z <- 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.