On Mon, 30 Apr 2001 apjaworski at mmm.com wrote:
> I am sure it is just me not understanding how R works, but could somebody
> explain why
>
> curve(cos(x))
>
> works and
>
> curve(expression(cos(x))
>
> does not?
The short answer is that cos(x) is an expression returning a real number
(the cosine of the value of x) but expression(cos(x)) is an expression
returning the expression cox(x), and so is not plottable.
R> x<-0
R> evalq(cos(x))
[1] 1
R> evalq(expression(cos(x)))
expression(cos(x))
> I have done some investigating and here is what I found. If I comment out
> the line of curve indicated below, both calls work fine.
When I comment out that line I get
R> curve(cos(x))
Error in xy.coords(x, y, xlabel, ylabel, log) :
x and y lengths differ
> function (expr, from, to, n = 101, add = FALSE, type = "l", ylab
= NULL,
> log = NULL, xlim = NULL, ...)
> {
> sexpr <- substitute(expr)
> if (is.name(sexpr)) {
> fcall <- paste(sexpr, "(x)")
> expr <- parse(text = fcall)
> if (is.null(ylab))
> ylab <- fcall
> }
> else {
> if (!(is.call(sexpr) && match("x",
all.vars(sexpr), nomatch = 0)))
> stop("'expr' must be a function or an expression
containing
> 'x'")
> # expr <- sexpr
> if (is.null(ylab))
> ylab <- deparse(sexpr)
> }
> lims <- if (is.null(xlim))
> < ... >
>
> This is confusing, since
>
> substitiue(expression(cos(x)))
>
> returns just
>
> expression(cos(x)).
>
> Must be some side effects I do not understand.
It's not side effects, it's evaluation. It's tricky.
Suppose you type
curve(cos(x))
Then expr contains a promise to compute the cosine of the value of x.
Since x may not exist, this promise will cause an error when the
evaluation is done (unless x happens to exist)
As expr is a formal parameter of the function, substitute(expr) returns
the unevaluated actual parameter, which is the expression cox(x).
This expression, when evaluated in an environment containing a suitable
vector x will return the vector of cosines of the values in x, which we
can plot.
OTOH if you type curve(expression(cos(x)) then expr contains a promise to
evaluate expression(cos(x)), which returns the expression cos(x). When
this is evaluated in a suitable environment you get the vector of cosines
of x. But substitute(expr) will now return the unevaluated expression
expression(cos(x)) and when you evaluate this you will get the expression
cos(x) rather than a vector of cosines of the values of x.
So the way the function is written it will work as documented, with your
change it will fail when it should work, unless the correct x vector is
coincidentally hanging around in the calling environment.
> What is even more confusing
> is that the above code (with one line commented out) does not work when
> called as
> curve(parse(text="cos(x)"))
>
> although
>
> parse(text="cos(x)")
>
> returns
>
> expression(cos(x)).
That's because curve() sneakily looks at the unevaluated parameter sexpr
before evaluating it, and notices it isn't an expression depending on the
symbol x (it's an expression depending on the string "cos(x)").
To prove this (it would be silly to do for any other reason) you can
confuse your modified curve() into working with
R> x<-"cos(x)"
R> curve(parse(text=x))
> What I am really trying to do is plot a rather compilcated expression that
> has been built from pieces by pasting strings together. SInce the parse
> function returns an expression I thought I could just feed the result of
> parse to plot ( or curve).
It's likely to be less painful to define a suitable vector x and use
eval() to evaluate the expression.
-thomas
Thomas Lumley Asst. Professor, Biostatistics
tlumley at u.washington.edu University of Washington, Seattle
-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-
r-help mailing list -- Read http://www.ci.tuwien.ac.at/~hornik/R/R-FAQ.html
Send "info", "help", or "[un]subscribe"
(in the "body", not the subject !) To: r-help-request at
stat.math.ethz.ch
_._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._