Вопрос

Я хотел бы понять логику, которую R использует при передаче аргументов функциям, создании копий переменных и т. д.что касается использования памяти.Когда он фактически создает копию переменной vs.просто передать ссылку на эту переменную?В частности, меня интересуют следующие ситуации:

f <- function(x) {x+1}
a <- 1
f(a)

Является a передается буквально или это ссылка на передаваемую информацию?

x <- 1
y <- x

Ссылка на копию?Когда это не так?

Если бы кто-нибудь мог объяснить мне это, я был бы очень признателен.

Это было полезно?

Решение

Когда он проходит переменные, он всегда является копией, а не посредством ссылки. Иногда, однако, вы не получите копию, сделанную, пока на самом деле не произойдет назначение. Реальное описание процесса - это пропуск. Посмотрите на документацию

?force
?delayedAssign
.

Одно практическое значение состоит в том, что очень трудно, если не невозможно избежать нужды, по крайней мере, вдвое больше баран, сколько ваши объекты номинально занимают. Изменение большого объекта, как правило, требует внесения временной копии.

Обновление: 2015: Я делаю (и сделал) согласиться с Matt Delyle, что его пакет Data.table предоставляет альтернативное маршруту для присваивания, которое позволяет избежать проблемы дублирования копирования. Если это было запрошенное обновление, то я не понял его в то время, когда было сделано предложение.

Было недавнее изменение в R 3.2.1 в правилах оценки для apply и Reduce. Это было так объявлено со ссылкой на новости здесь: Интересная статья, цитирующая Jetzel в комментариях, теперь здесь :

Другие советы

Поздний ответ, но это очень важный аспект языкового дизайна, который недостаточно освещается в Интернете (или, по крайней мере, в обычных источниках).

x <- c(0,4,2)
lobstr::obj_addr(x)
# [1] "0x7ff25e82b0f8"
y <- x
lobstr::obj_addr(y)
# [1] "0x7ff25e82b0f8"

Обратите внимание на одинаковый «адрес памяти», т.е.место в памяти, где хранится объект.Таким образом, вы можете подтвердить, что x и y оба указывают на один и тот же идентификатор.

Книга Хэдли Уикхема Advanced R касается этого:

Рассмотрим этот код:

x <- c(1, 2, 3)

Это легко прочитать так:«Создайте объект с именем« X », содержащий значения 1, 2 и 3».К сожалению, это упрощение, которое приведет к неточным прогнозам о том, что на самом деле делает R за кулисами.Более точно сказать, что этот код делает две вещи:

Он создает объект, вектор значений, c(1, 2, 3).И это связывает этот объект с именем, x.Другими словами, объект или значение не имеют имени;на самом деле значение имеет имя.

Обратите внимание, что эти адреса памяти являются эфемерными и меняются с каждым новым сеансом R.

Теперь вот важная часть.

В семантике R объекты копируются по значению.Это означает, что изменение копии оставляет исходный объект нетронутым.Поскольку копирование данных в памяти является дорогой операцией, копии в R максимально ленивы.Они происходят только тогда, когда новый объект действительно изменяется.Источник:[Документация по языку R][1]

Итак, если мы теперь изменим значение y добавляя значение к вектору, y теперь указывает на другой «объект».Это согласуется с тем, что говорится в документации относительно операции копирования, происходящей «только при изменении нового объекта» (ленивый). y указывает на другой адрес, чем был раньше.

y <- c(y, -3)
print(lobstr::obj_addr(y))
# [1] "0x7ff25e825b48"
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top