我想绘制由f
生成的函数fmaker
的曲线,以下方式错误:
fmaker <- function(a) function(x) a*x
curve(fmaker(2), 0, 10)
Error in curve(fmaker(2), 0, 10) :
'expr' must be a function, or a call or an expression containing 'x'
但如果我将fmaker(2)
分配给变量g
,则可以:
g <- fmaker(2)
curve(g, 0, 10)
我觉得很奇怪,因为在使用lapply
之类的其他功能时,这些功能没有任何区别:
lapply(list(1,2), g)
lapply(list(1,2), fmaker(2))
#both output correct answer
有人可以告诉我为什么吗?关于curve
有什么特别之处?
答案 0 :(得分:3)
原因是curve
在其第一个参数上使用non-standard evaluation - 而不是评估表达式,然后将其作为参数传递给curve
, R将未评估的表达式传递给curve
。
curve
然后在看到表达式是函数调用时尝试在其自己的上下文中计算表达式:
sexpr <- substitute(expr)
…
if (!((is.call(sexpr) || is.expression(sexpr)) && xname %in%
all.vars(sexpr)))
stop(gettextf("'expr' must be a function, or a call or an expression containing '%s'",
xname), domain = NA)
expr <- sexpr
其中xname = 'x'
和all.var
是一个函数,它返回未评估表达式中包含的所有变量。
这显然失败了(因为curve(2)
不包含x
)。你的第二个例子成功了,因为现在你没有将函数调用表达式传递给curve
,你传递一个变量(引用一个函数),所以curve
通过正常调用它来评估它:
if (is.name(sexpr)) {
expr <- call(as.character(sexpr), as.name(xname))
}
答案 1 :(得分:0)
(编辑)注意:这不回答OP问题(返回函数的函数),而是一个更典型的情况。
您需要在函数调用中包含“x”:
fmaker&lt; - function(x,a)a * x
曲线(fmaker(x,a = 2),0,10)