【问题标题】:How to reference an object between functions that are defined in the global environment如何在全局环境中定义的函数之间引用对象
【发布时间】:2020-07-06 20:00:34
【问题描述】:

我在下面创建了两个在全局环境中定义的函数。您会注意到foo()bar() 中被调用,它们共享一个输入,即x。 :

bar <- function() {
  x <- 2
  foo()
}

foo <- function(x) {
  x * 1000
}

bar() 中调用foo() 时未明确定义x,这会导致以下代码出错:

bar()

我的问题是:有没有办法定义foo() 试图找到x 的环境?根据我的研究,foo() 正在全球环境中寻找x,但理想情况下它应该从bar() 的环境中获取x,其中x &lt;- 2

我知道以下方法可以解决问题,但这不是我正在开发的代码中的合理选择。关键是让foo()bar()的环境中引用x的值:

bar <- function() {
  x <- 2
  foo(x = x)
}

foo <- function(x) {
  x * 1000
}

bar()

【问题讨论】:

  • 您可能需要指定环境
  • foo 的封闭环境是全局环境,因此它将在那里寻找x。您可以在bar 中定义foo
  • @akrun 我将如何指定环境?这会使用 eval() 吗?
  • 我不确定这个例子的所有测试用例。但是,如果你这样做 foo &lt;- function() { x* 1000 } 应该可以工作
  • 删除 x 作为函数参数对我不起作用。我收到错误object 'x' not found

标签: r


【解决方案1】:

您似乎应该在这里使用表达式来表示f 之类的函数。也许

foo <- quote(x * 1000)
bar <- function() {
  x <- 2
  eval(foo)
}
bar()
#[1] 2000

或者如果它必须是一个函数

foo <- function() {
  x * 1000 
}

bar <- function() {
  x <- 2
  environment(foo)<-environment()
  foo()
}
bar()
#[1] 2000

请注意,这不会永久更改foo,它只是在bar 中使用不同的封闭环境制作foo 的本地副本。

后一个解决方案很像我对上一个问题的解决方案:R specify function environment

【讨论】:

    【解决方案2】:

    这将为您提供类似于您想要的东西。诀窍是使用闭包来定义您想要的函数(/环境),然后使用双左箭头分配在bar 中分配 x 的值。双左箭头分配使您能够写入父环境中的变量。

    make_foo_bar_pair = function() {
      # Define the shared state...
      x <- 0
    
      # Make your bar function
      bar <- function() {
        x <<- 2 # Use the double left arrow assign to modify the shared state
        foo()
      }
      
      # Make your foo function
      foo <- function() {
        x * 1000 # Which references the shared state
      }
      
      # Return your linked functions...
      list(foo, bar)
    }
    
    # Make a pair of functions with shared state...
    pair = make_foo_bar_pair()
    foo = pair[[1]]
    bar = pair[[2]]
    
    # Call them
    foo() # 0 (foo uses the initial value of x that it closed over)
    bar() # 2000
    foo() # 2000
    

    您创建的每个foo/bar 对都将引用不同的x,因此重复调用make_foo_bar_pair 将为您提供新的foo/bar 函数,它们共享一个独特的x

    如果你真的需要使用全局环境,你可以这样做......

    # Make your bar function
    bar <- function() {
      x <<- 2 # Use the double left arrow assign to modify the shared state
      foo()
    }
      
    # Make your foo function
    foo <- function() {
      x * 1000 # Which references the shared state
    }
    

    ...但是在这样的全球环境中做事感觉就像是代码味道。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-12-23
      • 2022-01-04
      • 1970-01-01
      相关资源
      最近更新 更多