R 中的全局变量和局部变量

我是 R 的新手,我对 R 中局部和全局变量的用法很困惑。

我读了一些帖子在互联网上说,如果我使用 =<-我将分配的变量在当前的环境中,使用 <<-我可以访问一个全局变量时,在一个函数。

但是,我记得在 C + + 中,当你在方括号 {}中声明一个变量时,局部变量就会出现,所以我想知道这对于 R 是否也是一样的?或者只是对于 R 中的 功能,我们有局部变量的概念。

我做了一个小实验,这似乎表明,只有括号是不够的,我有什么错误吗?

{
x=matrix(1:10,2,5)
}
print(x[2,2])
[1] 4
182266 次浏览

函数内部声明的变量是该函数的局部变量。例如:

foo <- function() {
bar <- 1
}
foo()
bar

给出以下错误: Error: object 'bar' not found

如果你想让 bar成为一个全局变量,你应该这样做:

foo <- function() {
bar <<- 1
}
foo()
bar

在这种情况下,可以从函数外部访问 bar

但是,与 C、 C + + 或许多其他语言不同,方括号不确定变量的范围。例如,在下面的代码段中:

if (x > 10) {
y <- 0
}
else {
y <- 1
}

if-else语句之后仍然可以访问 y

正如您所说的,您还可以创建嵌套环境。您可以看看这两个链接,了解如何使用它们:

  1. Http://stat.ethz.ch/r-manual/r-devel/library/base/html/environment.html
  2. Http://stat.ethz.ch/r-manual/r-devel/library/base/html/get.html

这里有一个小例子:

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

<-在当前环境中进行分配。

当你在函数 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"

第一次打印时,我们还没有调用 foo,所以它应该仍然是全局的-这是有意义的。第二次打印时,在调用 baz之前,它在 foo内部,因此值“ infoo”是有意义的。下面是我们看到 <<-实际上在做什么的地方。打印的下一个值是“ in baz-before <-”,即使 print 语句位于 <<-之后。这是因为 <<-不在当前环境中查找(除非您处于全局环境中,在这种情况下,<<-的行为类似于 <-)。因此,在 baz内部,bar 的值保持为“ in baz-before <-”。一旦我们调用 bazfoo内部的条的副本就会被改为“ in baz”,但是我们可以看到全局 foo1没有改变。这是因为在 foo内部定义的 foo1的副本在我们创建 baz时位于父环境中,所以这是 <<-看到的 foo1的第一个副本,也就是它分配给它的副本。所以 <<-不仅仅是直接分配给全局环境。

<<-非常棘手,如果可以避免的话,我不推荐使用它。如果您确实想要赋值给全局环境,您可以使用赋值函数并明确地告诉它您想要赋值给全局环境。

现在我将 <<-改为一个赋值语句,我们可以看到它的效果:

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酒吧的值是“在 foo”,即使在调用 baz。这是因为 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"

差不多吧

attrs <- {}


attrs.a <- 1


f <- function(d) {
attrs.a <- d
}


f(20)
print(attrs.a)

将打印“1”

attrs <- {}


attrs.a <- 1


f <- function(d) {
attrs.a <<- d
}


f(20)
print(attrs.a)

将打印“20”