我们假设我们声明了这个函数:
f <- function(x) u + x
现在,如果我调用f(10)
R将递归地查找u
值的父环境,直到它到达全局环境,如果找到值,则返回u + 10
,否则我们会收到错误。到现在为止还挺好。
现在假设我们有一个池,我们希望在f
体内拉出未知值,如pool <- list(u = 10)
或带u
集的环境变量。
你如何将u
值注入通用函数f
?你能编写一个函数来注入pool
中f
中定义的变量吗?换句话说,我们可以指向R在哪个方向寻找缺失的变量而不是在父环境中递归查找?
编辑:我知道我当然可以做这个f <- function(x) pool[["u"]] + x
,但我正在寻找上述行为。
编辑:用例如下:我正在构建一个库,允许用户配置他们想要优化的函数,我希望它们可以使用在加载库时已经计算的某些变量(某些解决方案)微分方程)并按他们的意愿组合它们。所以我想让这个过程对它们尽可能透明,如果可能的话,让它们在函数体中使用变量值u
而不是pool$u
。
1)重置环境将pool
转换为环境并将f
的环境设置为:
# inputs
pool <- list(u = 10)
f <- function(x) u + x
environment(f) <- list2env(pool, parent = environment(f))
f(1)
## [1] 11
2)proto另一种可能性是使用proto包。 proto对象是具有修改方法的环境。将pool
转换为proto对象p
并将f
插入其中。将f
插入p
将其环境重置为p
所以:
library(proto)
p <- as.proto(pool, parent = environment(f))
p$f <- f
with(p, f(10)) # use the version of f inserted into p
## [1] 11
或者我们可以用f
中的f
版本覆盖p
:
library(proto)
p <- as.proto(pool, parent = environment(f))
p$f <- f
f <- with(p, f)
f(1)
## [1] 11
更新:已经设置了从pool
到f
的原始环境形成的新环境的父级,以便f
中的自由变量首先在pool
形成的环境中查找,然后f
的环境按此顺序查找,而不是源自pool
然后父项的环境帧。