简体   繁体   English

有人可以解释R中`<<-`赋值运算符的行为吗?

[英]Can someone explain the behaviour of `<<-` assignament operator in R?

After some hours I found a bug in my code because an unexpected behaviour of the <<- assinament operator in r. 几个小时后,我在代码中发现了一个错误,因为r中的<<- assinament运算符的意外行为。 I have read the documentation and browsed on internet but I still do not understand the behaviour of the operator. 我已经阅读了文档并浏览了Internet,但是我仍然不了解操作员的行为。

Look these two functions: 查看以下两个功能:

# Define a function a_counter
a_counter  <- function(){

  i <<- i + 1
  print(i)

}
> i <- 0
> a_counter()
[1] 1
> print(i)
[1] 1
> a_counter()
[1] 2
> print(i)
[1] 2
# Define a function not_a_counter
not_a_counter  <- function(){

  i <- 0
  i <<- i + 1
  print(i)

}
> i <- 0
> not_a_counter()
[1] 0
> print(i)
[1] 1
> not_a_counter()
[1] 0
> print(i)
[1] 1

The first chunk of code runs as I expected, the variable i in both environments (function env. and global env.) are increased in each function call. 第一部分代码按我的预期运行,在每个环境调用(函数环境和全局环境)中的变量i都增加了。

The second chunk of code is absolutely unexpected for me. 第二段代码对我来说绝对是意外的。 The i <<- i + 1 does not assign the value to the i located in the function environment, but it does so in the i located in the global environment. i <<- i + 1不分配值到i所在的功能环境,但在这样做, i位于全球环境。 I expected both enviroments to be updated. 我希望两个环境都可以更新。

In your a_counter , there is only one value of i . 在您的a_counter ,只有i一个值。 Not two. 不是两个。 When a "free variable" is found in a function, it's looked up in the environment in which the function was defined. 当在函数中找到“自由变量”时,将在定义该函数的环境中对其进行查找。 So when you call i in that function, it goes up to the global environment to find the value. 因此,当您在该函数中调用i时,它将取决于全局环境以查找值。 Then when you do <<- , assignment doesn't happen in the function environment at all. 然后,当您执行<<- ,函数环境中根本不会发生分配。 <<- always starts looking in the parent environment. <<-总是开始在父环境中查找。 If you look at 如果你看

counter_vars  <- function() {
  a <- 4 
  i <<- i + 1
  ls() 
}
counter_vars()
# [1] "a"

you'll see that the only variable inside the function environment/closure is the a variable. 您会看到函数环境/闭包内部的唯一变量是a变量。 The i variable doesn't exist there. i变量在那里不存在。 So with the original function all the i s come from global scope 因此,与原来的功能全部i š来自全球范围内

a_counter  <- function(){    
  i <<- i + 1    # global i = global i + 1
  print(i)       # global i still (no local variable has been created)
}

So the behavior you see in not_a_counter should be expected because <<- will not change values in current environment. 所以应该在not_a_counter看到您的行为,因为<<-不会在当前环境中更改值。 It always start looking one environment "up". 它总是开始寻找一个“向上”的环境。 When you have 当你有

not_a_counter  <- function(){    
  i <- 0         # local i (always 0)
  i <<- i + 1    # global i == local i + 1 (always 0+1)
  print(i)       # local i (always still 0, local value not changed)
}

The i variable is no longer "free" once you define it in the function. 在函数中定义后, i变量不再“空闲”。 So i <- 0 creates a local variable, in the i <<- i + 1 part, the right hand side i+1 uses that local variable and assigns to the i in the parent environment. 所以i <- 0创建一个局部变量,在i <<- i + 1一部分,右边i+1使用该本地变量并分配给i在父环境。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM