<- 在当前环境下赋值。
当你在一个函数中时,R 会为你创建一个新环境。默认情况下,它包含创建它的环境中的所有内容,因此您也可以使用这些变量,但您创建的任何新内容都不会写入全局环境。
在大多数情况下,<<- 将分配给已经在全局环境中的变量,或者在全局环境中创建一个变量,即使您在函数内部也是如此。然而,它并不像那样简单。它的作用是检查父环境以查找具有感兴趣名称的变量。如果它在您的父环境中找不到它,它会转到父环境的父环境(在创建函数时)并在那里查找。它继续向上到全局环境,如果在全局环境中找不到它,它将在全局环境中分配变量。
这可能说明正在发生的事情。
bar <- "global"
foo <- function(){
bar <- "in foo"
baz <- function(){
bar <- "in baz - before <<-"
bar <<- "in baz - after <<-"
print(bar)
}
print(bar)
baz()
print(bar)
}
> bar
[1] "global"
> foo()
[1] "in foo"
[1] "in baz - before <<-"
[1] "in baz - after <<-"
> bar
[1] "global"
我们第一次打印 bar 我们还没有调用 foo 所以它应该仍然是全局的 - 这是有道理的。我们第二次在调用baz 之前打印它在foo 的内部,所以“in foo”的值是有意义的。下面是我们看到<<- 实际在做什么的地方。打印的下一个值是“in baz - <<- 之后。这是因为<<- 不查看当前环境(除非您在全局环境中,在这种情况下<<- 的行为类似于<-)。所以在baz 内部,bar 的值保持为“in baz - before baz,foo 内部的 bar 副本就会更改为“in baz”,但我们可以看到全局 bar 没有改变。这是因为foo 内部定义的bar 的副本在我们创建baz 时位于父环境中,因此这是<<- 看到的bar 的第一个副本,因此它分配给它的副本.所以<<- 不只是直接分配给全局环境。
<<- 很棘手,如果可以避免的话,我不建议使用它。如果您真的想分配给全局环境,您可以使用 assign 函数并明确告诉它您要全局分配。
现在我将<<- 更改为assign 语句,我们可以看到它有什么效果:
bar <- "global"
foo <- function(){
bar <- "in foo"
baz <- function(){
assign("bar", "in baz", envir = .GlobalEnv)
}
print(bar)
baz()
print(bar)
}
bar
#[1] "global"
foo()
#[1] "in foo"
#[1] "in foo"
bar
#[1] "in baz"
所以我们两次在foo 内打印 bar,即使在调用baz 之后,值也是“in foo”。这是因为 assign 甚至从未考虑过 foo 内部的 bar 的副本,因为我们告诉它确切的位置。但是,这一次全局环境中 bar 的值发生了变化,因为我们在那里显式分配了。
现在您还询问了创建局部变量的问题,您也可以很容易地做到这一点,而无需创建函数……我们只需要使用 local 函数。
bar <- "global"
# local will create a new environment for us to play in
local({
bar <- "local"
print(bar)
})
#[1] "local"
bar
#[1] "global"