<-
在当前环境中进行分配。
当您在函数内部时,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
它,因此它仍然应该是全局的-这很有意义。第二次打印它是foo
在调用之前进行的,baz
因此“ in foo”中的值有意义。以下是我们看到<<-
实际在做什么的地方。即使print语句在<<-
。之后,下一个打印的值仍是“在baz-<<之前” 。这是因为<<-
它不在当前环境中查看(除非您处于全局环境中,在这种情况下的<<-
行为类似于<-
)。因此baz
,bar的值内部保持为“ in baz-<<-之前”。一旦我们调用baz
了内部的bar副本,其副本foo
将更改为“ in baz”,但正如我们看到的那样,全局变量bar
未更改。bar
是的内部定义foo
是在父环境时,我们创造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 为“ in foo” baz
。这是因为assign
从未考虑过bar
foo内部的副本,因为我们告诉了它确切的位置。但是,这次更改了全局环境中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"
globalenv(); globalenv() %>% parent.env; globalenv() %>% parent.env %>% parent.env
,…