如何在全局环境中定义的函数之间引用对象



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

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

bar()中调用foo()时,没有显式定义x,这会导致以下代码出错:

bar()

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

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

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

似乎您应该在这里对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 指定函数环境

这将为您提供类似于您想要的东西。诀窍是使用闭包来定义你想要的函数(/environment(,然后使用双左箭头赋值在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将为您提供共享不同x的新鲜foo/bar函数。

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

# 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
}

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

最新更新