自动分配

Auto assignment

最近我一直在使用从同事那里继承的一组 R 脚本。这对我来说是一个值得信赖的来源,但我不止一次在他的代码自动分配中发现

x <<- x

这种操作是否有任何意义?

<<- 

是一个全局赋值运算符,我认为几乎没有理由使用它,因为它会产生副作用。
在任何情况下,当一个人想要定义一个全局变量或一个比当前环境高一级的变量时,它的使用范围就可以了。

例如:

x <- NA

test <- function(x) {
 x <<- x
}

> test(5)
> x
#[1] 5

这是一个简单的用法,<<- 将进行父环境搜索(嵌套函数声明的情况),如果找不到则在全局环境中分配。

通常这是一个非常糟糕的主意TM,因为您无法真正控制变量的分配位置,并且您可能会覆盖某个地方用于其他目的的变量.

这是一种将函数中定义的值复制到全局环境(或至少是父环境堆栈中的某处)的机制:来自 ?"<<-"

The operators ‘<<-’ and ‘->>’ are normally only used in functions, and cause a search to be made through parent environments for an existing definition of the variable being assigned. If such a variable is found (and its binding is not locked) then its value is redefined, otherwise assignment takes place in the global environment.

我不认为这是特别好的做法(R 是一种主要是函数式的语言,通常最好避免函数副作用),但它确实有所作为。 (@Roland 在评论中指出,@BrianO'Donnell 在他的回答中指出 [引用 Thomas Lumley] 使用 <<- 如果您使用它修改函数闭包,如 demo(scoping)。根据我的经验,它更常被误用于构造全局变量,而不是干净地使用函数闭包。)

考虑这个例子,从 empty/clean 环境开始:

f <- function() {
     x <- 1     ## assignment
     x <<- x    ## global assignment
}

在我们调用f()之前:

x
## Error: object 'x' not found

现在调用 f() 并重试:

f()
x
## [1] 1

艾伦给出了一个很好的答案:Use the superassignment operator <<- to write upstairs

Hadley也给出了很好的答案:How do you use "<<-" (scoping assignment) in R?.

有关 'superassignment' 运算符的详细信息,请参阅 Scope

以下是 R 手册中关于 Assignment Operators 部分中有关运算符的一些重要信息:

"The operators <<- and ->> are normally only used in functions, and cause a search to be made through parent environments for an existing definition of the variable being assigned. If such a variable is found (and its binding is not locked) then its value is redefined, otherwise assignment takes place in the global environment."

Thomas Lumley 总结得很好:"The good use of superassignment is in conjuction with lexical scope, where an environment stores state for a function or set of functions that modify the state by using superassignment."