-->

(作用域分配)中的R - 你是如何“<<”使用?(作用域分配)中的R - 你是如何“

2019-05-10 09:40发布

我刚刚读完关于在R介绍作用域 ,和我对很好奇<<-分配。

手册显示一个(非常有趣),例如用于<<-这我觉得我的理解。 我现在仍然缺少的是当这可能是有用的上下文。

所以,我很想读你的实例(或链接的例子)上的时候使用<<-可以是有趣/有用。 什么可能是使用它的危险性(它看起来容易松动轨道的),你可能会觉得像共享任何提示。

Answer 1:

<<-与关闭维护状态结合最有用的。 下面是最近矿井纸部分:

闭包是由另一个函数编写一个函数。 闭包是所谓的,因为它们包围父函数的环境,并且可以访问该函数的所有变量和参数。 这是有用的,因为它可以让我们拥有的参数两个层次。 参数一个级别(父)控制功能是如何工作的。 其他级别(孩子)做的工作。 下面的示例演示如何使用这个想法产生一个家庭的电源功能。 父函数( power )创建子功能( squarecube ),实际上做的辛勤工作。

power <- function(exponent) {
  function(x) x ^ exponent
}

square <- power(2)
square(2) # -> [1] 4
square(4) # -> [1] 16

cube <- power(3)
cube(2) # -> [1] 8
cube(4) # -> [1] 64

在两个层面来管理变量的能力,也能够通过允许函数修改其父的环境变量保持整个函数调用的状态。 关键在不同层面管理的变量是双箭头赋值运算符<<- 不同于通常的单箭头分配( <-总是工作在目前的水平,双箭头操作者可以修改父级别的变量。

这使得有可能维持,记录了多少次的函数被调用,如下面的示例显示了一个柜台。 每次new_counter运行时,它创建了一个环境,初始化计数器i在这种环境中,然后创建一个新的功能。

new_counter <- function() {
  i <- 0
  function() {
    # do something useful, then ...
    i <<- i + 1
    i
  }
}

新功能是关闭的,其环境是封闭的环境。 当关闭counter_onecounter_two正在运行,每一个修改在其封闭环境中的计数器,然后返回当前计数。

counter_one <- new_counter()
counter_two <- new_counter()

counter_one() # -> [1] 1
counter_one() # -> [1] 2
counter_two() # -> [1] 1


Answer 2:

它有助于想到<<-等同于assign (如果设置的inherits在功能参数TRUE )。 的利益assign是它允许你指定更多的参数(例如环境),所以我更喜欢使用assign<<-在大多数情况下。

使用<<-assign(x, value, inherits=TRUE)意味着“包封所提供的环境的环境中进行搜索,直到变量‘X’遇到”。 换句话说,它会继续通过环境才能走,直到它找到与该名字的变量,这将其分配给。 这可能是一个功能的范围内,或在全球环境。

为了了解这些功能做什么,你需要(例如,使用也明白[R环境search )。

我经常使用,当我运行大型模拟这些功能,我想保存中间结果。 这允许你创建对象的给定功能的范围内,或apply循环。 这是非常有帮助的,特别是如果你有关于意外结束一个大循环(如数据库断开),在这种情况下,你可能会失去在这个过程中一切任何担心。 这将相当于在长期运行过程中写你的成绩列到数据库或文件,只是它的存储R环境中的结果,而不是。

我这个初级警告:要小心,因为你现在使用全局变量的工作,使用特别是当<<- 这意味着,可以使用的情况下结束,其中一个功能是使用来自环境中的对象的值,当预期将使用一个供给作为参数它。 这是该函数编程试图避免(见主事情之一的副作用 )。 我避免这个问题通过赋予我的价值观为唯一的变量名(使用贴有一组或唯一参数)从来没有在函数内使用,但只是用于缓存,并在情况下,我需要恢复以后(或者做一些元 - 分析在中间结果)。



Answer 3:

在这里我用一个地方<<-在使用Tcl / tk的简单图形用户界面。 一些最初的例子有它 - 因为你需要为状态(statefullness)局部和全局变量之间的区别。 例如见

 library(tcltk)
 demo(tkdensity)

它采用<<- 否则,我同意马立克:) - 谷歌搜索可以提供帮助。



Answer 4:

f <- function(n, x0) {x <- x0; replicate(n, (function(){x <<- x+rnorm(1)})())}
plot(f(1000,0),typ="l")


Answer 5:

<<-操作员也可以成为有用的写作参考方法时,引用类 。 例如:

myRFclass <- setRefClass(Class = "RF",
                         fields = list(A = "numeric",
                                       B = "numeric",
                                       C = function() A + B))
myRFclass$methods(show = function() cat("A =", A, "B =", B, "C =",C))
myRFclass$methods(changeA = function() A <<- A*B) # note the <<-
obj1 <- myRFclass(A = 2, B = 3)
obj1
# A = 2 B = 3 C = 5
obj1$changeA()
obj1
# A = 6 B = 3 C = 9


Answer 6:

在这个问题上,我想指出的是, <<-操作者会表现奇怪,当一个for循环中应用(错误地)(可能还有其他的情况下也是如此)。 考虑下面的代码:

fortest <- function() {
    mySum <- 0
    for (i in c(1, 2, 3)) {
        mySum <<- mySum + i
    }
    mySum
}

你可能会认为该函数将返回预期的总和,6,而是返回0,有一个全局变量mySum被创建并分配值3。我不能完全解释这到底是怎么回事,但肯定的身体for循环是不是一个新的范围“等级”。 相反,它似乎是R看起来之外fortest功能,无法找到一个mySum变量分配到,所以创建一个,并将值1,第一次循环。 在后续的迭代中,在RHS必须参照(不变)内的分配mySum变量而LHS是指全局变量。 因此每次迭代覆盖全局变量的该迭代的值的值i ,因此它具有上,当退出函数值3。

希望这可以帮助别人 - 这难倒我今天几个小时! (顺便说一句,只需更换<<-<-和功能按预期工作)。



文章来源: How do you use “<<-” (scoping assignment) in R?