From: Steven McKinney <smckinney_at_bccrc.ca>

Date: Mon, 09 Jun 2008 19:52:40 -0700

# 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

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

work -- but then of

# course the user can't specify his own y-label

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?

y<-y+(y==0)*1e-50

#cat(xlab,ylab,'\n')

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