了解R中的变量范围

时间:2012-10-09 15:18:32

标签: r scope environment-variables environment

如何在以下代码段中修改变量'loco'的值:

poco <- function() {

func <- function(x) {
    print(loco)
    loco <- loco+x
}

loco <- 123
func(1)
func(2)
}

此函数给出以下结果:

> poco()
[1] 123
[1] 123

4 个答案:

答案 0 :(得分:5)

poco <- function() {

func <- function(x) {
    print(loco)
    loco <<- loco+x
}

loco <- 123
func(1)
func(2)
}

<<-运算符分配给外部作用域。 (如assign(..., env=...))。但是,正如评论中所提到的,这通常是一个坏主意。如果您想在第二个问题上进一步提出问题,那么我认为还有其他更好的选择。

如果你不小心的话,<<-会让你陷入困境。见wiki article

loco <- loco + x的第一个函数中发生的事情是func loco func的范围超出loco的范围,当它发现它引入本地范围时poco并在本地范围而不是{{1}}范围内分配给{{1}}。

希望有所帮助!

答案 1 :(得分:5)

R有一堆环境。因此,当您使用简单的<-=命令更改函数内的变量时,其值不会在外部环境中更改。

为此,您有几个选项,如下所示:

第一选项:

func <- function(x) {
    print(loco)
    # To modify value of "loco" just in the parent environment, but not globally
    loco <<- loco+x
}

第二(更好)选项:

func <- function(x) {
    print(loco)
    # Again modifies the varaible just in the parent environment, not globally
    assign("loco", loco + x, envir = sys.frame(-1))
}

第三种选择:

func <- function(x) {
    print(loco)
    # To modify the value of a global variable "loco"
    assign("loco", loco + x, envir = .GlobalEnv) 
}

然后你会:

loco <- 123
func(1) # 123
func(2) # 124
loco    # 126

请注意,通过使用选项1和2,如果您有多个嵌套函数定义,则只是在父函数中修改值,而不是全局修改。

答案 2 :(得分:3)

poco <- function() {

  func <- function(loco,x) {
    print(loco)
    loco <- loco+x
    loco
  }

  loco <- 123
  loco <- func(loco,1)
  loco <- func(loco,2)
  loco
}
loco_final <- poco()
#[1] 123
#[1] 124
loco_final
#[1] 126

答案 3 :(得分:3)

一般来说,loco在函数中没有改变是件好事。不使用这些全局变量可确保变量不会干扰较大脚本中的每个变量。

假设您在blafunction_a中使用变量function_b。预测函数调用的结果很困难,因为它取决于bla的历史记录。在行话中,这被称为功能具有副作用。不使用这些使得函数更可预测,更容易调试。此外,当您的脚本增长时,您可以防止新功能或代码片段发生更改bla时出现任何问题,从而更改功能中发生的情况。

通常,如果您需要函数中的变量,请将其作为变量传递。但是,R确实允许从函数内部到函数外部进行作用域,但反之则不然。有关详细信息,另请参阅此recent question