为了账号安全,请及时绑定邮箱和手机立即绑定

如何在R中使用“<-”(范围分配)?

如何在R中使用“<-”(范围分配)?

有只小跳蛙 2019-07-27 15:15:04
如何在R中使用“<-”(范围分配)?我刚读完R简介中的范围界定,我很好奇<<-任务。手册给出了一个(非常有趣)的例子<<-我觉得我能理解。我仍然缺少的是什么情况下这可能是有用的。因此,我想从您这里读到的是示例(或指向示例的链接)。<<-可能是有趣的/有用的。使用它的危险是什么(看起来很容易失控),以及任何您可能想分享的提示。
查看完整描述

3 回答

?
湖上湖

TA贡献2003条经验 获得超2个赞

<<-与闭包一起维护状态最有用。以下是我最近的一篇论文中的一节:

闭包是由另一个函数编写的函数。闭包之所以被称为闭包,是因为它们围封父函数的环境,并可以访问该函数中的所有变量和参数。这很有用,因为它允许我们有两个级别的参数。一个级别的参数(父级)控制函数的工作方式。另一层(孩子)做这项工作。下面的示例演示如何使用此思想生成一系列幂函数。父函数(power)创建子函数(squarecube)这实际上是一项艰苦的工作。

power <- function(exponent) {
  function(x) x ^ exponent}square <- power(2)square(2) # -> [1] 4square(4) # -> [1] 16cube <- power(3)cube(2) # -> [1] 8cube(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] 1counter_one() # -> [1] 2counter_two() # -> [1] 1



查看完整回答
反对 回复 2019-07-28
?
宝慕林4294392

TA贡献2021条经验 获得超8个赞

它有助于思考<<-相当于assign(如果设置inherits函数中的TRUE)。.的利益assign它允许您指定更多的参数(例如环境),所以我更喜欢使用assign过关<<-在大多数情况下。

使用<<-assign(x, value, inherits=TRUE)意味着“搜索所提供环境的封闭环境,直到遇到变量‘x’。”换句话说,它将继续按顺序遍历环境,直到找到一个具有该名称的变量,并将其赋值给该变量。这可以在函数的范围内,也可以在全局环境中。

为了了解这些函数的作用,您还需要了解R环境(例如,使用search).

在运行大型模拟时,我经常使用这些函数,并且希望保存中间结果。这允许您在给定函数的作用域之外创建对象,或者apply循环。这是非常有帮助的,特别是如果您对大循环意外结束(例如数据库断开)有任何担心,在这种情况下,您可能会丢失整个过程中的所有内容。这相当于在长时间运行的过程中将结果写入数据库或文件,而不是将结果存储在R环境中。

我对此的主要警告是:要小心,因为您现在正在处理全局变量,特别是在使用<<-..这意味着,当您期望函数使用作为参数提供的对象值时,您可能会遇到这样的情况:函数正在使用来自环境的对象值。这是函数式编程试图避免的主要问题之一(请参阅副作用)。我通过将值赋值给函数中从未使用过的唯一变量名(使用带有集合或唯一参数的粘贴)来避免这个问题,但只用于缓存,以防以后需要恢复(或对中间结果进行一些元分析)。




查看完整回答
反对 回复 2019-07-28
  • 3 回答
  • 0 关注
  • 585 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信