我是R的新手,我对R中局部变量和全局变量的使用感到困惑.
我在互联网上阅读了一些帖子,说如果我使用=或者<-我将在当前环境中分配变量,并且<<-我可以在函数内部访问全局变量.
但是,正如我记得在C++中,只要你在括号内声明一个变量就会出现局部变量{},所以我想知道这对于R来说是否相同?或者仅仅是R中的函数我们有局部变量的概念.
我做了一个小实验,这似乎表明只有括号是不够的,我有什么不对吗?
{
x=matrix(1:10,2,5)
}
print(x[2,2])
[1] 4
Run Code Online (Sandbox Code Playgroud)
bet*_*ido 143
在函数内声明的变量是该函数的本地变量.例如:
foo <- function() {
bar <- 1
}
foo()
bar
Run Code Online (Sandbox Code Playgroud)
出现以下错误:Error: object 'bar' not found.
如果你想创建bar一个全局变量,你应该这样做:
foo <- function() {
bar <<- 1
}
foo()
bar
Run Code Online (Sandbox Code Playgroud)
在这种情况下bar,可以从函数外部访问.
但是,与C,C++或许多其他语言不同,括号不确定变量的范围.例如,在以下代码段中:
if (x > 10) {
y <- 0
}
else {
y <- 1
}
Run Code Online (Sandbox Code Playgroud)
yif-else声明后仍然可以访问.
正如您所说,您还可以创建嵌套环境.您可以查看这两个链接以了解如何使用它们:
这里有一个小例子:
test.env <- new.env()
assign('var', 100, envir=test.env)
# or simply
test.env$var <- 100
get('var') # var cannot be found since it is not defined in this environment
get('var', envir=test.env) # now it can be found
Run Code Online (Sandbox Code Playgroud)
Das*_*son 125
<- 在当前环境中进行分配.
当您在函数内部时,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"
Run Code Online (Sandbox Code Playgroud)
我们第一次打印吧我们还没有打电话foo,所以它应该仍然是全局的 - 这是有道理的.我们第二次foo在调用之前将其打印出来,baz因此"foo"中的值是有意义的.以下是我们看到<<-实际行动的地方.打印的下一个值是"in baz - before << - ",即使print语句出现在<<-.这是因为<<-没有查看当前环境(除非您处于全局环境中,在这种情况下<<-就像这样<-).所以在bazbar的值内部保持"在baz - 之前<< - ".一旦我们调用baz内部的bar副本foo变为"in baz",但我们可以看到全局bar不变.这是因为我们在创建时在父环境中bar定义了它的副本,因此这是它看到的第一个副本,因此它分配给它的副本.所以不只是直接分配到全球环境.foobazbar<<-<<-
<<-很棘手,如果你能避免它,我不建议使用它.如果您确实要分配给全局环境,可以使用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"
Run Code Online (Sandbox Code Playgroud)
因此,foo即使在调用之后,我们两次打印条形内部的值都是"in foo" baz.这是因为我们assign从未考虑过barfoo内部的副本,因为我们告诉它确切的位置.但是,这次全局环境中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"
Run Code Online (Sandbox Code Playgroud)
小智 5
同样的道理
attrs <- {}
attrs.a <- 1
f <- function(d) {
attrs.a <- d
}
f(20)
print(attrs.a)
Run Code Online (Sandbox Code Playgroud)
将打印“1”
attrs <- {}
attrs.a <- 1
f <- function(d) {
attrs.a <<- d
}
f(20)
print(attrs.a)
Run Code Online (Sandbox Code Playgroud)
将打印“20”