一个同事问了我这个问题,我也为此苦恼过。
假设我想定义一个函数,它以一个表达式(比如说
如果我想简单地完成这个任务,我只需要运行
我可以通过在函数内使用
好的,那么这表明我可能应该尝试一下。
这里的
假设我想定义一个函数,它以一个表达式(比如说
x^2
)作为参数,并将该参数传递给 curve()
。如果我想简单地完成这个任务,我只需要运行
curve(x^2,from=0,to=3)
并且它很好地运行。
假设我尝试设置一个包装函数(假设除了绘制曲线外,我还想在包装器中做其他事情):
f <- function(g) {
curve(g,from=0,to=3)
}
如果我传递一个函数,这个方法就可以正常工作:
f(function(x) x^2)
如果我尝试传递 x^2
,当 R 尝试评估表达式时会失败:
f(x^2)
## Error in eval(expr, envir, enclos) (from #2) : object 'x' not found
我可以通过在函数内使用
substitute
来试图防止这种情况发生:f0 <- function(g) {
str(substitute(g))
curve(substitute(g),from=0,to=3)
}
f0(x^2)
## language x^2
## Error in curve(substitute(g), from = 0, to = 3) (from #3) :
## 'expr' must be a function, or a call or an expression containing 'x'
好的,那么这表明我可能应该尝试一下。
f <- function(g) {
h <- as.expression(substitute(g))
str(h)
curve(as.expression(substitute(g)),from=0,to=3)
}
f(x^2)
## expression(x^2)
## Error in curve(as.expression(substitute(g)), from = 0, to = 3) (from #4) :
## 'expr' must be a function, or a call or an expression containing 'x'
就目前而言,
- 使用
curve(h,...)
时会以不同的方式失败(显示“未找到函数h
”) - 如果用
as.call()
代替as.expression()
,结果也会以相同方式失败 - 无论如何,
curve()
都不能处理表达式:
curve(expression(x^2),from=0,to=1)
## Error in curve(expression(x^2), from = 0, to = 1) :
## 'expr' did not evaluate to an object of length 'n'
如果我尝试调试curve()
以查看发生了什么,我们会得到:
sexpr <- substitute(expr)
...
if (!((is.call(sexpr) || is.expression(sexpr)) && xname %in%
all.vars(sexpr)))
stop(...)
这里的
sexpr
是substitute(g)
,它未通过xname %in% all.vars(sexpr)
测试... 有什么想法如何处理这个问题吗?
do.call
吗?它似乎可以像lm
、glm
等函数一样工作。 - Rich Scriven