georgi.boshnakov at manchester.ac.uk
2010-Jan-20 10:35 UTC
[Rd] function curve() (PR#14191)
Full_Name: Georgi Boshnakov Version: 2.10.1pat OS: Windows XP Submission from: (NULL) (130.88.123.205) When calling programmatically function curve() from package:graphics I experienced some trouble since it reports stop("'expr' must be a function or an expression containing 'x'") even if expr is "expression". Naturally, the user message uses "expression" in its usual generic meaning but it is somewhat confusing that an object of type "expression" is rejected. The message is produced in the following piece in the source of function curve() else { if (!(is.call(sexpr) && match("x", all.vars(sexpr), nomatch = 0L))) stop("'expr' must be a function or an expression containing 'x'") expr <- sexpr if (is.null(ylab)) ylab <- deparse(sexpr) } The "if" statement only checks with is.call, and not with is.expression. Maybe it is worth including the check with is.expression, e.g. as in else { if (!((is.call(sexpr) || is.expression(sexpr)) && match("x", all.vars(sexpr), nomatch = 0L) )) stop("'expr' must be a function or an expression containing 'x'") expr <- sexpr if (is.null(ylab)) ylab <- deparse(sexpr) } Example: # use curve() mycurveA <- function(x,from=1,to=10){ xloc <- parse(text=x) # call("mycurve0",expr=xloc,from=from,to=to) do.call("curve",list(expr=xloc,from=from,to=to)) } # use curve modified as suggested above. mycurveB <- function(x,from=1,to=10){ xloc <- parse(text=x) # call("mycurve0",expr=xloc,from=from,to=to) do.call("mycurve0",list(expr=xloc,from=from,to=to)) }> mycurveA("x^2")Error in curve(expr = expression(x^2), from = 1, to = 10) : 'expr' must be a function or an expression containing 'x'> mycurveB("x^2")# (no error, plots the graph) Best regards, Georgi Boshnakov
You may have figured this out already, but you can get a "call" object from parse() by extracting its first element, as in mycurveC <- function(x,from=1,to=10){ xloc <- parse(text=x)[[1]] do.call("curve",list(expr=xloc,from=from,to=to)) } mycurveC("(x-4) ** 2") This doesn't address the confusion you note, but it is an easy way of getting your code to work without needing any functions to be redefined. -- Tony Plate georgi.boshnakov at manchester.ac.uk wrote:> Full_Name: Georgi Boshnakov > Version: 2.10.1pat > OS: Windows XP > Submission from: (NULL) (130.88.123.205) > > > When calling programmatically function curve() from package:graphics I > experienced some trouble since it reports > stop("'expr' must be a function or an expression containing 'x'") > even if expr is "expression". Naturally, the user message uses "expression" in > its usual generic meaning but it is somewhat confusing that an object of type > "expression" is rejected. > > The message is produced in the following piece in the source of function > curve() > > else { > if (!(is.call(sexpr) && match("x", all.vars(sexpr), nomatch = 0L))) > stop("'expr' must be a function or an expression containing 'x'") > expr <- sexpr > if (is.null(ylab)) > ylab <- deparse(sexpr) > } > > The "if" statement only checks with is.call, and not with is.expression. > Maybe it is worth including the check with is.expression, e.g. as in > > else { > if (!((is.call(sexpr) || is.expression(sexpr)) && > match("x", all.vars(sexpr), nomatch = 0L) > )) > stop("'expr' must be a function or an expression containing 'x'") > expr <- sexpr > if (is.null(ylab)) > ylab <- deparse(sexpr) > } > > > Example: > > # use curve() > mycurveA <- > function(x,from=1,to=10){ > xloc <- parse(text=x) > # call("mycurve0",expr=xloc,from=from,to=to) > do.call("curve",list(expr=xloc,from=from,to=to)) > } > > # use curve modified as suggested above. > mycurveB <- > function(x,from=1,to=10){ > xloc <- parse(text=x) > # call("mycurve0",expr=xloc,from=from,to=to) > do.call("mycurve0",list(expr=xloc,from=from,to=to)) > } > > >> mycurveA("x^2") >> > Error in curve(expr = expression(x^2), from = 1, to = 10) : > 'expr' must be a function or an expression containing 'x' > > >> mycurveB("x^2") >> > # (no error, plots the graph) > > > Best regards, > Georgi Boshnakov > > ______________________________________________ > R-devel at r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-devel > >