В чем разница между assign () и << - в R? - PullRequest
13 голосов
/ 26 апреля 2011

Обычный подход к написанию функций в R (как я понимаю) - избегать побочных эффектов и возвращать значение из функции.

contained <- function(x) {
  x_squared <- x^2
  return(x_squared)
}

В этом случае возвращается значение, вычисленное на основе ввода в функцию.Но переменная x_squared недоступна.

Но если вам нужно нарушить этот основной принцип функционального программирования (и я не уверен, насколько серьезен R в этом вопросе) и вернуть объект из функции,у вас есть два варианта.

escape <- function(x){
  x_squared  <<- x^2
  assign("x_times_x", x*x, envir = .GlobalEnv)
}

Оба объекта x_squared и x_times_x возвращаются.Один метод предпочтительнее другого и почему так?

Ответы [ 3 ]

18 голосов
/ 26 апреля 2011

Томас Ламли отвечает на это в превосходном сообщении на r-help на днях . <<- - это окружающая среда, поэтому вы можете сделать что-то подобное (и снова я цитирую его сообщение от 22 апреля в этой теме ):

make.accumulator<-function(){
    a <- 0
    function(x) {
        a <<- a + x
        a
    }
}

> f<-make.accumulator()
> f(1)
[1] 1
> f(1)
[1] 2
> f(11)
[1] 13
> f(11)
[1] 24

Это законное использование <<- в качестве "супер-назначения" с лексической областью действия. И не просто назначить в глобальной среде. Для этого у Томаса есть следующие слова:

Зло и Зло используют для модификации переменные в глобальной среде.

Очень хороший совет.

2 голосов
/ 26 апреля 2011

Согласно странице руководства здесь ,

Операторы <<- и ->> вызывают поиск в среде для существующего определения переменной, являющейсяназначены.

Мне никогда не приходилось делать это на практике, но, на мой взгляд, assign выигрывает много очков за точное указание среды, даже не думая о правилах области видимости R.<<- выполняет поиск по средам, и поэтому его немного сложнее интерпретировать.

РЕДАКТИРОВАТЬ: В отличие от @Dirk и @Hadley, похоже, что assign - это подходящий способ для фактического назначенияглобальная среда (когда это то, что вы знаете, что вы хотите), тогда как <<- является подходящим способом "подняться" в более широкую область.

0 голосов
/ 11 июня 2015

Как указал @John в своем ответе, assign позволяет вам конкретно указать среду. Конкретное заявление будет в следующем:

testfn <- function(x){

    x_squared <- NULL

    escape <- function(x){
        x_squared  <<- x^2
        assign("x_times_x", x*x, envir = parent.frame(n = 1))
    }

    escape(x)

    print(x_squared)
    print(x_times_x)
}

, где мы используем <<- и assign. Обратите внимание, что если вы хотите использовать <<- для присвоения окружению функции верхнего уровня, вам нужно объявить / инициализировать переменную. Однако с assign вы можете использовать parent.frame(1) для указания инкапсулирующей среды.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...