[R] substitute question
Tony Plate
tplate at blackmesacapital.com
Thu Mar 18 16:41:54 CET 2004
This is because of the saved attribute "source" on z (that doesn't get
printed out before evaluating z, because z is not yet then a function).
To complete your example:
> z <- substitute( function(){a+1}, list(a=quote(b)) )
> z
function() {
b + 1
}
> eval(z)
function(){a+1}
> ze <- eval(z)
> attributes(ze)
$source
[1] "function(){a+1}"
> attr(ze, "source") <- NULL
> ze
function ()
{
b + 1
}
>
I previously wrote on this topic:
Date: Fri, 24 Oct 2003 09:42:55 -0600
To: R-help at stat.math.ethz.ch, Peter Dalgaard <p.dalgaard at biostat.ku.dk>
From: Tony Plate <tplate at blackmesacapital.com>
Subject: Re: [R] what's going on here with substitute() ?
Mime-Version: 1.0
Content-Type: text/plain; charset="us-ascii"; format=flowed
Peter, thank you for the explanation. This is indeed what is happening.
Might I suggest the following passage for inclusion in the help page for
"function", and possibly also "body", in the DETAILS or WARNING section:
"Note that the text of the original function definition is saved as an
attribute "source" on the function, and this is printed out when the
function is printed. Hence, if the function body is changed in some way
other than by assigning a value via body() (which removes the "source"
attribute), the printed form of the function may not be the same as the
actual function body."
Something along these lines could also go in the help for "eval", though if
it were only there it might be very difficult to find if one were trying to
look up puzzling behavior of a function.
Here is a transcript that shows what is happening, with another suggestion
following it.
> eval(substitute(this.is.R <- function() X,
list(X=!is.null(options("CRAN")[[1]]))))
> this.is.R
function() X
> body(this.is.R)
[1] TRUE
> attributes(this.is.R)
$source
[1] "function() X"
> attributes(this.is.R) <- NULL
> this.is.R
function ()
TRUE
> # the "source" attribute comes from function definition:
> attributes(function() X)
$source
[1] "function() X"
> # and seems to be added by "eval":
> attr(eval(parse(text="function() TRUE")[[1]]), "source")
[1] "function() TRUE"
>
> # we can assign bogus "source"
> attr(this.is.R, "source") <- "a totally bogus function body"
> this.is.R
a totally bogus function body
> # assigning to body() removes "source"
> body(this.is.R) <- list(666)
> this.is.R
function ()
666
> attr(this.is.R, "source")
NULL
>
An even better approach might be something that gave a warning on printing
if the parsed "source" attribute was not identical to the language object
being printed. This would probably belong in the code for "case LANGSXP:"
in the function PrintValueRec in main/print.c (if it were written in R, I
could contribute a patch, but right now I don't have time to try to
understand the C there.) R code to do the test could be something like this:
> f <- this.is.R
> identical(f, eval(parse(text=attr(f, "source"))[[1]]))
[1] FALSE
> f <- function() TRUE
> identical(f, eval(parse(text=attr(f, "source"))[[1]]))
[1] TRUE
>
-- Tony Plate
At Wednesday 08:09 PM 3/17/2004, Gabor Grothendieck wrote:
>I left out the brackets in my last email but the problem
>(a reappears after have been substituted out) still remains:
>
> > z <- substitute( function(){a+1}, list(a=quote(b)) )
> > z
>function() {
> b + 1
>}
> > eval(z)
>function(){a+1}
>
>
>
>---
>Date: Wed, 17 Mar 2004 20:10:43 -0500 (EST)
>From: Gabor Grothendieck <ggrothendieck at myway.com>
>[ Add to Address Book | Block Address | Report as Spam ]
>To: <R-help at stat.math.ethz.ch>
>Subject: [R] substitute question
>
>
>
>
>
>
>Consider the following example:
>
># substitute a with b in the indicated function. Seems to work.
> > z <- substitute( function()a+1, list(a=quote(b)) )
> > z
>function() b + 1
>
># z is an object of class call so use eval
># to turn it into an object of class expression; however,
># when z is evaluated, the variable a returns.
> > eval(z)
>function()a+1
>
>Why did a suddenly reappear again after it had already been replaced?
>
>______________________________________________
>R-help at stat.math.ethz.ch mailing list
>https://www.stat.math.ethz.ch/mailman/listinfo/r-help
>PLEASE do read the posting guide! http://www.R-project.org/posting-guide.html
More information about the R-help
mailing list