Об этом коллега спросил меня, и я боролся с этим.Передача выражений кривой() внутри функции
Предположим, я хочу определить функцию, которая принимает выражение (допустим, 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' и т. Д. –