2013-02-14 3 views
21

Я прочитал this basic question о переименовании объектов и ответе @Shane на него, указывая на ленивую оценку. Теперь мне интересно, оценивается ли assign лениво. Так же, как здесь:Ленивая оценка в R - назначается пострадавшим?

assign("someNewName",someOldObject) 
rm(someOldObject) 

Причина, почему мне интересно об этом заключается в следующем использования: Предположим, я получил объекты 10K + R, каждый из которых имеет два атрибута, называемых originalName и additionalName. Теперь я хочу написать функцию, которая может позволить пользователю переключиться с одного имени на другое без потери этих двух атрибутов. Примерно так ...

EDIT: на основании ввода Хэдли я изменил свой код.

switchObjectName <- function(x) { 
    n1 <- attributes(x)$originalName 
    n2 <- attributes(x)$additionalName 
    objName <- deparse(substitute(x)) 
    if(objName == n1) { 
    delayedAssign(n2,x,assign.env=.GlobalEnv) 
    } else { 
    delayedAssign(n1,x,assign.env=.GlobalEnv) 
    } 
    rm(list=c(objName),envir=.GlobalEnv)  
} 

это работает хорошо, но у меня было довольно много проблем, чтобы получить право rm заявления. Я попробовал rm(objName,envir=.GlobalEnv), но не смог заставить его работать, хотя objName определенно является символом, потому что это результат deparse(substitute(x).

+12

Если я правильно понял ваш вопрос, см. «DelayedAssign», https://github.com/hadley/pryr/blob/master/R/assign-delayed.r и раздел «Назначение: привязка имен к значениям» на https://github.com/hadley/devtools/wiki/environments – hadley

+0

еще раз спасибо. особенно, что указатель на главу в вашей вики помог мне понять, что происходит на самом деле. 'delayedAssign' был правильным намеком. –

ответ

5

Язык R обычно имеет семантику значения. Назначение x <- y означает, что x и y будут независимыми копиями одного и того же объекта (обновления на y и x будут независимыми). Наивная реализация x <- y всегда выделяла память для x и полностью копировала y в нее. Вместо этого GNU-R использует механизм копирования на запись, он откладывает копию до тех пор, пока не произойдет обновление, что экономит время памяти/времени выполнения, если это не произойдет. Пользователи R не должны знать об этой оптимизации, они полностью прозрачны (за исключением некоторых редких случаев, таких как ошибки из памяти). Этот механизм применяется к присвоению, обозначенному как x <- y и assign("x", y) одинаково.

Оценка Леничная оценка является частью конструкции этого языка и видима для пользователей/программистов R. Выражения, переданные в качестве аргументов функции, например. в foo(ls()) переданное выражение равно ls(), оцениваются лениво, только если и когда это необходимо для реализации вызываемой функции.

delayedAssign - это низкоуровневая функция, видимая пользователям/программистам R, но она действительно используется только для ленивой загрузки пакетов и не нужна в пользовательских программах. delayedAssign позволяет указать выражение для вычисления значения переменной; вычисление будет происходить лениво, только если /, когда переменная читается в первый раз.

Итак, чтобы ответить на вопрос, назначение в R всегда «лениво» в том, что используется механизм копирования на запись. Вычисление правой части присваивания может быть также ленивым (с использованием delayedAssign), но это не должно быть необходимо/использовано пользовательскими программами.

Я думаю, что для «переименования» переменных нет необходимости использовать delayedAssign (потому что правая сторона не вычисляется). Это только усложняет ситуацию и, вероятно, будет накладные расходы на производительность из-за бухгалтерского учета delayedAssign. Я бы просто использовал обычное задание, если мне пришлось переименовывать переменные.

Для ясности кода я также по возможности старался избегать удаления переменных из среды и даже назначения из функции в глобальную среду, например. Я бы просто создал новый список и ввел в него новые привязки (переменные).

Упомянув механизм копирования на запись, с текущей реализацией в GNU-R, любое из описанных решений потенциально может вызвать копирование памяти, которое не было бы необходимым, если бы переменные не были переименованы. Невозможно избежать этого на уровне R.

Смежные вопросы