Re: [R] Puzzled over curve() syntax.

From: Duncan Murdoch <>
Date: Fri 28 Oct 2005 - 00:29:38 EST

On 10/27/2005 9:50 AM, Rolf Turner wrote:
> It's probably toadally elementary (and, like, duhhhhh) but
> I can't figure out why the following doesn't work:
> curve(function(x){qnorm(x,4,25)},from=0,to=1)
> I get the error:
> Error in xy.coords(x, y, xlabel, ylabel, log) :
> 'x' and 'y' lengths differ
> But if I do
> foo <- function(x){qnorm(x,4,25)}
> curve(foo,from=0,to=1)
> it goes like a train.
> Also
> plot(function(x){qnorm(x,4,25)},from=0,to=1)
> works just fine.
> I'm using
> > version
> _
> platform sparc-sun-solaris2.9
> arch sparc
> os solaris2.9
> system sparc, solaris2.9
> status
> major 2
> minor 2.0
> year 2005
> month 10
> day 06
> svn rev 35749
> language R
> This is just idle curiousity I guess, but I would like to deepen my
> understanding. There's probably something about the ``expression''
> concept that I'm not grokking here ....

It's the way curve is written (and documented, though perhaps a little obscurely). If you debug it, you'll see that eventually your function gets assigned to a variable called "expr", and a nice list of values gets assigned to "x", then it tries to evaluate

  y <- eval(expr, envir = list(x = x), enclos = parent.frame())

But if you evaluate expr, you just get the function back, you don't call it. The problem is that curve was written assuming you'd call it as


in which case the expression "qnorm(x,4,25)" gets evaluated at those x values and things are fine.

I don't think this is a bug, but it might be worth fixing so your code works too. It's a little tricky, because to know that you passed a function in, you probably want to evaluate it; but if you evaluate "qnorm(x,4,25)" before you've set up x, you'll get an error.

A fix is to add an additional else clause after the first test, namely

     else if (is.language(sexpr) && identical(sexpr[[1]],"function"))) {

           expr <- substitute(, list(x)), list(expr=expr))
           if (is.null(ylab))
               ylab <- deparse(sexpr)

but this still doesn't handle the case where you've given a more general expression that returns a function, e.g. picking one out of a list. You'll probably need another argument to distinguish the case of an expression returning y values from an expression returning a function, and I'm not sure that level of elaboration would really be a good idea.

Duncan Murdoch mailing list PLEASE do read the posting guide! Received on Fri Oct 28 04:33:43 2005

This archive was generated by hypermail 2.1.8 : Fri 28 Oct 2005 - 06:18:36 EST