Re: [R] substitute() reading data instead of name

From: Steven McKinney <smckinney_at_bccrc.ca>
Date: Mon, 09 Jun 2008 19:52:40 -0700

Hi Carl,

This is happening because of 'lazy evaluation'. Arguments to a function are not evaluated until they are needed. Thus the xlab and ylab deparsing is not happening until you pass them off to the plot() function. By this time you have altered y inside your function.

If you comment out your line of code
'y<-y+(y==0)*1e-50' you'll see
the correct labels on your plot.

But with this line in play, you have a local variable 'y' in your function's environment so that is what substitute() evaluates.

Before this line, y is still a formal
argument, so that is what substitute will evaluate.

When you add the dreck line of code,
you force lazy evaluation of the
ylab argument before you create an internal y variable in the function's environment. At that point y is still a formal argument so in the lazy evaluation you pick up the argument's name.

You can either put code such as these first two lines to grab the names of x and y before you alter x and y in your function

badplot <-
function(x, y, ylab, xlab, ...)
{
if (missing(ylab)) ylab <- deparse(substitute(y)) if (missing(xlab)) xlab <- deparse(substitute(x))
# un-comment either of the next two lines usually fixes the bug. why?
# cat(ylab,'\n')
# dreck<-ylab
# creating yy and using it instead of the input y fixes the bug. why?
#yy<-y
#yy<-yy+(yy==0)*1e-50
#y<-y+(y==0)*1e-50
#cat(xlab,ylab,'\n')
#plot(x,yy,xlab=xlab, ylab=ylab, ...)

plot(x,y,xlab=xlab, ylab=ylab, ...)

}

or use another mechanism such as match.call()

anotherbadplot <-
function(x, y, ylab=match.call()$y,
xlab=match.call()$x, ...)
{
# un-comment either of the next two lines usually fixes the bug. why?
# cat(ylab,'\n')
# dreck<-ylab
# creating yy and using it instead of the input y fixes the bug. why?
#yy<-y
#yy<-yy+(yy==0)*1e-50
y<-y+(y==0)*1e-50
#cat(xlab,ylab,'\n')
#plot(x,yy,xlab=xlab, ylab=ylab, ...)
plot(x,y,xlab=xlab, ylab=ylab, ...)

}

but I don't see any bug here.

HTH Steve McKinney

-----Original Message-----
From: r-help-bounces_at_r-project.org on behalf of Carl Witthoft Sent: Mon 6/9/2008 5:38 PM
To: r-help_at_r-project.org
Subject: [R] substitute() reading data instead of name  

I seem to have run across a bug in which substitute() inside a function definition gets 'confused.' The code is listed below. The same behavior occurs under OSX 10.3.9, PPC, w/ R2.2 and Rgui 1.14 and under OSX 10.4.11 Intel w/ 2.70 and the latest Rgui.

What I see is that 'xlab' properly has the name of the data I entered for the x-input. But 'ylab' contains the string ' c( {all the data values in the y-input vector}) ' .
If I un-comment the 'cat(ylab)' line or the 'dreck<-y' line, or if I create yy<-y and use yy from there on out, everything works properly.

So, is this a bug, or am I a foolish n00b, or do I need to "flush" something?

thanks for your help.
Carl

Here is the function .



# sample of odd behavior when using deparse(substitute()) in function
#call.
# I only see this w/ two or more such substitute() calls; use or don't
#use deparse(), no
# change in this behavior.
# If I do anything w/ ylab (cat it, or create dreck from it) then things
#seem to work
# If I pull the deparsing outside the function definition, it seems to
work -- but then of
# course the user can't specify his own y-label
#seems to be related to my conditional modification of y itself -- if
#comment out
# that line (y+(y==0)*1e-50) everything works. That y->yy seems to fix
#it as well.
#
badplot<-function(x, y, ylab=deparse(substitute(y)), xlab=deparse(substitute(x)), ...)
{
# un-comment either of the next two lines usually fixes the bug. why?
# cat(ylab,'\n')
# dreck<-ylab
# creating yy and using it instead of the input y fixes the bug. why?
#yy<-y
#yy<-yy+(yy==0)*1e-50
y<-y+(y==0)*1e-50
#cat(xlab,ylab,'\n')
#plot(x,yy,xlab=xlab, ylab=ylab, ...)
plot(x,y,xlab=xlab, ylab=ylab, ...)

}



As the comments say, doing just about any task that involves the input variable 'y' cleans up the problem.

R-help_at_r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide http://www.R-project.org/posting-guide.html and provide commented, minimal, self-contained, reproducible code.

R-help_at_r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide http://www.R-project.org/posting-guide.html and provide commented, minimal, self-contained, reproducible code. Received on Tue 10 Jun 2008 - 02:55:21 GMT

Archive maintained by Robert King, hosted by the discipline of statistics at the University of Newcastle, Australia.
Archive generated by hypermail 2.2.0, at Tue 10 Jun 2008 - 09:30:43 GMT.

Mailing list information is available at https://stat.ethz.ch/mailman/listinfo/r-help. Please read the posting guide before posting to the list.

list of date sections of archive