Skip to content

plotting an expression

2 messages · apjaworski@mmm.com, Thomas Lumley

#
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?

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.

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.  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)).


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).

Any help or explanation will be appreciated,

Andy

-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-
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
_._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._
#
On Mon, 30 Apr 2001 apjaworski at mmm.com wrote:

            
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))
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
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.
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))
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
_._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._