我正在尝试使用-package中的curve3d
函数emdbook
来创建在另一个函数内部本地定义的函数的等高线图,如以下最小示例所示:
library(emdbook)
testcurve3d <- function(a) {
fn <- function(x,y) {
x*y*a
}
curve3d(fn(x,y))
}
Run Code Online (Sandbox Code Playgroud)
出乎意料的是,这会产生错误
> testcurve3d(2)
Error in fn(x, y) : could not find function "fn"
Run Code Online (Sandbox Code Playgroud)
而相同的想法与-package 的更基本curve
功能一起正常工作base
:
testcurve <- function(a) {
fn <- function(x) {
x*a
}
curve(a*x)
}
testcurve(2)
Run Code Online (Sandbox Code Playgroud)
问题是如何curve3d
重写它以使其表现如预期.
您可以暂时attach
将功能环境添加到搜索路径以使其工作:
testcurve3d <- function(a) {
fn <- function(x,y) {
x*y*a
}
e <- environment()
attach(e)
curve3d(fn(x,y))
detach(e)
}
Run Code Online (Sandbox Code Playgroud)
分析
问题来自于以下方面curve3d
:
eval(expr, envir = env, enclos = parent.frame(2))
Run Code Online (Sandbox Code Playgroud)
在这一点上,我们看起来是10帧深,并fn
在中定义parent.frame(8)
.所以你可以编辑一行curve3d
来使用它,但我不确定这是多么强大.也许parent.frame(sys.nframe()-2)
可能更强大,但?sys.parent
警告可能会有一些奇怪的事情发生:
严格地说,sys.parent和parent.frame引用父解释函数的上下文.因此,内部函数(可能会或可能不会设置上下文,因此可能会或可能不会出现在调用堆栈中)可能不会被计算,并且S3方法也可以做出令人惊讶的事情.
注意延迟评估的影响:这两个函数在评估它们时查看调用堆栈,而不是在它们被调用时.将调用作为函数参数传递给它们不太可能是个好主意.