我面临一个关于 do.call 和曲线的奇怪问题:
func1 <- function (m, n) {
charac <- paste ("func2 <- function(x)", m, "*x^", n, sep = "")
eval(parse(text = charac))
return(func2)
}
func3 <- function (m, n) {
my.func <- func1 (m, n)
do.call("curve",list(expr = substitute(my.func)))
}
func1 构造 func2 和 func3 绘制构建的 func2 。 但是当我运行 func3 时,会显示以下错误:
> func3 (3, 6)
Error in curve(expr = function (x) :
'expr' must be a function, or a call or an expression containing 'x'
但是,当我运行 func1 并手动绘制输出(不应用 func3 )时,会绘制 func2 :
my.func <- func1 (3, 6)
do.call("curve",list(expr = substitute(my.func)))
这里发生的事情让我感到困惑,我不知道为什么 do.call 无法在 func3 本地环境中绘制 func2 。
谢谢
答案 0 :(得分:3)
你使这个过于复杂 - 在创建f2
时你不需要做任何特别的事情:
f1 <- function (m, n) {
function(x) m * x ^ n
}
f3 <- function (m, n) {
f2 <- f1(m, n)
curve(f2)
}
f3(3, 6)
当然,通过取消f1
:
f4 <- function (m, n) {
f2 <- function(x) m * x ^ n
curve(f2)
}
f4(3, 6)
找到有关R的范围规则的更多信息(这使得这项工作成为可能)
答案 1 :(得分:1)
这不是do.call
的问题,而是substitute
在全局环境中默认评估的问题。
所以你需要告诉它必须在哪个环境替换。这显然在func3的本地环境中。
这应该有效:
do.call("curve",list(expr = substitute(my.func,
env = parent.frame())))
编辑感谢Dwin
如评论中所述,替换env默认为当前评估环境。那么为什么下面的代码有效呢?答案在substitute
函数的形式参数或使用显式创建 delayedAssign(),promise的表达式槽替换了 符号。如果它是普通变量,则其值被替换, 除非env是.GlobalEnv,否则符号保持不变。
env = parent.frame(n=1)
相当于.GlobalEnv
,这就是为什么符号(my.func)保持不变。所以正确的答案是:
do.call("curve",list(expr = substitute(my.func,
env = .GlobalEnv)))
要测试,我打开新的R会话:
func1 <- function (m, n) {
charac <- paste ("func2 <- function(x)", m, "*x^", n, sep = "")
eval(parse(text = charac))
return(func2)
}
func3 <- function (m, n) {
my.func <- func1 (m, n)
do.call("curve",list(expr = substitute(my.func,env = .GlobalEnv)))
}
比我打电话
func3(2,6)
答案 2 :(得分:1)
这有效:
func3 <- function (m, n) {
my.func <- func1 (m, n); print(str(my.func))
do.call(curve, list(expr=bquote( my.func) ) )
}
答案 3 :(得分:-2)
您只需要删除行:
my.func&lt; - func1(m,n)