assign()和

时间:2021-08-01 23:44:34

The normal approach to writing functions in R (as I understand) is to avoid side-effects and return a value from a function.

用R编写函数的常规方法(如我所知)是避免副作用并从函数中返回值。

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

In this case, the value computed from the input into the function is returned. But the variable x_squared is not available.

在这种情况下,返回从函数的输入中计算的值。但是变量x_squared不可用。

But if you need to violate this basic functional programming tenet (and I'm not sure how serious R is about this issue) and return an object from a function, you have two choices.

但是,如果您需要违背这个基本的函数编程原则(我不确定R对于这个问题有多严重),并从函数返回一个对象,那么您有两个选择。

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

Both objects x_squared and x_times_x are returned. Is one method preferable to the other and why so?

返回对象x_squared和x_times_x。一种方法比另一种更可取吗?为什么?

3 个解决方案

#1


18  

Thomas Lumley answers this in a superb post on r-help the other day. <<- is about the enclosing environment so you can do thing like this (and again, I quote his post from April 22 in this thread):

托马斯·拉姆利(Thomas Lumley)在《r-help》(r-help)杂志上的一篇精彩文章中回答了这个问题。<<-是关于封闭环境的,所以你可以这样做(同样,我在这篇文章中引用了他4月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

This is a legitimate use of <<- as "super-assignment" with lexical scope. And not simply to assign in the global environment. For that, Thomas has these choice words:

这是<< <- as "super-assignment"在词法上的合理使用。而不仅仅是在全球环境中进行分配。为此,托马斯选择了以下字眼:

The Evil and Wrong use is to modify variables in the global environment.

恶意和错误的用法是修改全局环境中的变量。

Very good advice.

非常好的建议。

#2


2  

According to the manual page here,

根据这里的手册页,

The operators <<- and ->> cause a search to made through the environment for an existing definition of the variable being assigned.

操作符<<-和->>导致在环境中搜索正在分配的变量的现有定义。

I've never had to do this in practice, but to my mind, assign wins a lot of points for specifying the environment exactly, without even having to think about R's scoping rules. The <<- performs a search through environments and is therefore a little bit harder to interpret.

我从来没有在实践中这样做过,但是在我看来,为精确地指定环境而赋值可以赢得很多分数,甚至不需要考虑R的范围规则。<-在环境中执行搜索,因此有点难于解释。

EDIT: In deference to @Dirk and @Hadley, it sounds like assign is the appropriate way to actually assign to the global environment (when that's what you know you want), while <<- is the appropriate way to "bump up" to a broader scope.

编辑:在对@Dirk和@Hadley的尊重中,听起来好像是分配给全局环境的适当方式(当你知道你想要的时候),而<<-是“提升”到更大范围的适当方式。

#3


0  

As pointed out by @John in his answer, assign lets you specify the environment specifically. A specific application would be in the following:

正如@John在他的回答中指出的,赋值允许您明确指定环境。具体的申请如下:

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)
}

where we use both <<- and assign. Notice that if you want to use <<- to assign to the environment of the top level function, you need to declare/initialise the variable. However, with assign you can use parent.frame(1) to specify the encapsulating environment.

我们同时使用< <和赋值。请注意,如果您想使用<< <-来分配到顶层函数的环境,您需要声明 初始化变量。但是,通过assign,您可以使用parent.frame(1)来指定封装环境。< p>

#1


18  

Thomas Lumley answers this in a superb post on r-help the other day. <<- is about the enclosing environment so you can do thing like this (and again, I quote his post from April 22 in this thread):

托马斯·拉姆利(Thomas Lumley)在《r-help》(r-help)杂志上的一篇精彩文章中回答了这个问题。<<-是关于封闭环境的,所以你可以这样做(同样,我在这篇文章中引用了他4月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

This is a legitimate use of <<- as "super-assignment" with lexical scope. And not simply to assign in the global environment. For that, Thomas has these choice words:

这是<< <- as "super-assignment"在词法上的合理使用。而不仅仅是在全球环境中进行分配。为此,托马斯选择了以下字眼:

The Evil and Wrong use is to modify variables in the global environment.

恶意和错误的用法是修改全局环境中的变量。

Very good advice.

非常好的建议。

#2


2  

According to the manual page here,

根据这里的手册页,

The operators <<- and ->> cause a search to made through the environment for an existing definition of the variable being assigned.

操作符<<-和->>导致在环境中搜索正在分配的变量的现有定义。

I've never had to do this in practice, but to my mind, assign wins a lot of points for specifying the environment exactly, without even having to think about R's scoping rules. The <<- performs a search through environments and is therefore a little bit harder to interpret.

我从来没有在实践中这样做过,但是在我看来,为精确地指定环境而赋值可以赢得很多分数,甚至不需要考虑R的范围规则。<-在环境中执行搜索,因此有点难于解释。

EDIT: In deference to @Dirk and @Hadley, it sounds like assign is the appropriate way to actually assign to the global environment (when that's what you know you want), while <<- is the appropriate way to "bump up" to a broader scope.

编辑:在对@Dirk和@Hadley的尊重中,听起来好像是分配给全局环境的适当方式(当你知道你想要的时候),而<<-是“提升”到更大范围的适当方式。

#3


0  

As pointed out by @John in his answer, assign lets you specify the environment specifically. A specific application would be in the following:

正如@John在他的回答中指出的,赋值允许您明确指定环境。具体的申请如下:

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)
}

where we use both <<- and assign. Notice that if you want to use <<- to assign to the environment of the top level function, you need to declare/initialise the variable. However, with assign you can use parent.frame(1) to specify the encapsulating environment.

我们同时使用< <和赋值。请注意,如果您想使用<< <-来分配到顶层函数的环境,您需要声明 初始化变量。但是,通过assign,您可以使用parent.frame(1)来指定封装环境。< p>