[R] 'substitute' question

2007-03-13 Thread remko duursma

# I use this code to label a graph with the R2:

# graph
x - rnorm(100)
y - x + rnorm(100)
lm1 - lm(y~x)
plot(x,y)

# label
R2text - substitute(paste(R^2, = ,r2),list(r2=r2))
text(1,-3,R2text, col=red)

# i have modified this a bit, so that i have a vector with other labels, 
each of which
# will be labelled on the graph. Example:
texts - c(And the R2 is, R2text)
x - c(-2,-2)
y - c(2,1)
for(i in 1:length(texts))text(x[i],y[i],texts[i],pos=4, col=blue)

# As you can see the label R2 = 48.7 remains at paste(R^2,  = , 48.7)
# What to do?



Thanks for your help,

Remko



..-~-.-~-.-~-.-~-.-~-.-~-.-~-.-~-.-~-
Remko Duursma
Post-doctoral researcher
Dept. Forest Ecology
University of Helsinki, Finland

_
With tax season right around the corner, make sure to follow these few 
simple tips.

__
R-help@stat.math.ethz.ch 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.


Re: [R] 'substitute' question

2007-03-13 Thread Stephen Tucker
hi,

your first argument to substitute should be an expression, not a character
string (which the output of paste() will give you)

so...
# first assign to variable r2 (think you forgot to do that)
# in your example
r2 - summary(lm1)$r.squared

# then to your label
R2text - substitute(R^2==r2,list(r2=round(r2,2)))

# then you can annotate with text() as you did

alternatively, you can use 
R2text - bquote(R^2==.(round(r2,2)))


--- remko duursma [EMAIL PROTECTED] wrote:

 
 # I use this code to label a graph with the R2:
 
 # graph
 x - rnorm(100)
 y - x + rnorm(100)
 lm1 - lm(y~x)
 plot(x,y)
 
 # label
 R2text - substitute(paste(R^2, = ,r2),list(r2=r2))
 text(1,-3,R2text, col=red)
 
 # i have modified this a bit, so that i have a vector with other labels, 
 each of which
 # will be labelled on the graph. Example:
 texts - c(And the R2 is, R2text)
 x - c(-2,-2)
 y - c(2,1)
 for(i in 1:length(texts))text(x[i],y[i],texts[i],pos=4, col=blue)
 
 # As you can see the label R2 = 48.7 remains at paste(R^2,  = , 48.7)
 # What to do?
 
 
 
 Thanks for your help,
 
 Remko
 
 
 
 ..-~-.-~-.-~-.-~-.-~-.-~-.-~-.-~-.-~-
 Remko Duursma
 Post-doctoral researcher
 Dept. Forest Ecology
 University of Helsinki, Finland
 
 _
 With tax season right around the corner, make sure to follow these few 
 simple tips.
 
 __
 R-help@stat.math.ethz.ch 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.
 



 

Finding fabulous fares is fun.

__
R-help@stat.math.ethz.ch 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.


Re: [R] 'substitute' question

2007-03-13 Thread Mendiburu, Felipe \(CIP\)
Dear Renko

To modify the script

plot(x,y)
r2-summary(lm1)$r.squared*100
# label
R2text - substitute(paste(R^2, = ,r2),list(r2=r2))
text(-1,1,R2text, col=red) # To see of the coordinates of the graph.

Grettings

Felipe

-Original Message-
From: [EMAIL PROTECTED]
[mailto:[EMAIL PROTECTED] Behalf Of remko duursma
Sent: Tuesday, March 13, 2007 8:02 AM
To: r-help@stat.math.ethz.ch
Subject: [R] 'substitute' question



# I use this code to label a graph with the R2:

# graph
x - rnorm(100)
y - x + rnorm(100)
lm1 - lm(y~x)
plot(x,y)

# label
R2text - substitute(paste(R^2, = ,r2),list(r2=r2))
text(1,-3,R2text, col=red)

# i have modified this a bit, so that i have a vector with other labels, 
each of which
# will be labelled on the graph. Example:
texts - c(And the R2 is, R2text)
x - c(-2,-2)
y - c(2,1)
for(i in 1:length(texts))text(x[i],y[i],texts[i],pos=4, col=blue)

# As you can see the label R2 = 48.7 remains at paste(R^2,  = , 48.7)
# What to do?



Thanks for your help,

Remko



..-~-.-~-.-~-.-~-.-~-.-~-.-~-.-~-.-~-
Remko Duursma
Post-doctoral researcher
Dept. Forest Ecology
University of Helsinki, Finland

_
With tax season right around the corner, make sure to follow these few 
simple tips.

__
R-help@stat.math.ethz.ch 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@stat.math.ethz.ch 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.


Re: [R] 'substitute' question

2007-03-13 Thread Bojanowski, M.J. \(Michal\)
I do not understand why you play with 'substitute' instead of something
like this:

# CAUTION: this will work only for bivariate case

# plotmaking function
plotModel - function(m)
{
x - m$model$x
y - m$model$y
r2 - summary(m)$r.squared
plot(x,y)
abline(m)
text( min(x), max(y), paste(And the R^2 is, round(r2,3)),
pos=4)
invisible(NULL)
}

# your data
x - rnorm(100)
y - x + rnorm(100)
lm1 - lm(y~x)
# make the plot
plotModel(lm1)



*** Note that my e-mail address has changed to [EMAIL PROTECTED]
*** Please update your address books accordingly. Thank you!

_
Michal Bojanowski
ICS / Sociology
Utrecht University
Heidelberglaan 2; 3584 CS Utrecht
Room 1428
[EMAIL PROTECTED]
http://www.fss.uu.nl/soc/bojanowski
-Original Message-
From: [EMAIL PROTECTED]
[mailto:[EMAIL PROTECTED] On Behalf Of remko duursma
Sent: Tuesday, March 13, 2007 2:02 PM
To: r-help@stat.math.ethz.ch
Subject: [R] 'substitute' question


# I use this code to label a graph with the R2:

# graph
x - rnorm(100)
y - x + rnorm(100)
lm1 - lm(y~x)
plot(x,y)

# label
R2text - substitute(paste(R^2, = ,r2),list(r2=r2)) text(1,-3,R2text,
col=red)

# i have modified this a bit, so that i have a vector with other labels,
each of which # will be labelled on the graph. Example:
texts - c(And the R2 is, R2text)
x - c(-2,-2)
y - c(2,1)
for(i in 1:length(texts))text(x[i],y[i],texts[i],pos=4, col=blue)

# As you can see the label R2 = 48.7 remains at paste(R^2,  = ,
48.7)
# What to do?



Thanks for your help,

Remko



..-~-.-~-.-~-.-~-.-~-.-~-.-~-.-~-.-~-
Remko Duursma
Post-doctoral researcher
Dept. Forest Ecology
University of Helsinki, Finland

_
With tax season right around the corner, make sure to follow these few
simple tips.

__
R-help@stat.math.ethz.ch 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@stat.math.ethz.ch 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.


Re: [R] 'substitute' question

2007-03-13 Thread Bojanowski, M.J. \(Michal\)
I'm sorry for my first post as I did not properly understood your
problem.
The reason why you were getting paste(R^2,  = , 48.7) instead of the
properly formatted R^2=48.7
is that in creating 'texts' in your code you were mixing character
string with expressions resulting in 'texts' being a list not a vector.
The only modification to make is to index texts with double square
brackets as below

# the figure
x - rnorm(100)
y - x + rnorm(100)
lm1 - lm(y~x)
plot(x,y)
# label
R2text - substitute(paste(R^2, = ,r2),list(r2=r2)) text(1,-3,R2text,
col=red)

# i expanded your list of labels to four elements...
texts - c(And the R2 is, R2text, third label, fourth label)
# texts is a list not an atomic vector
class(texts)
str(texts)

# ... and added more coordinates accordingly
x - c(-2,-2, -1, -1)
y - c(2,1, 2, 1)
# here 'texts[[i]]' instead of 'texts[i]'
for(i in 1:length(texts))text(x[i],y[i], texts[[i]],pos=4, col=blue)

hth,
Michal


*** Note that my e-mail address has changed to [EMAIL PROTECTED]
*** Please update your address books accordingly. Thank you!

_
Michal Bojanowski
ICS / Sociology
Utrecht University
Heidelberglaan 2; 3584 CS Utrecht
Room 1428
[EMAIL PROTECTED]
http://www.fss.uu.nl/soc/bojanowski
-Original Message-
From: [EMAIL PROTECTED]
[mailto:[EMAIL PROTECTED] On Behalf Of remko duursma
Sent: Tuesday, March 13, 2007 2:02 PM
To: r-help@stat.math.ethz.ch
Subject: [R] 'substitute' question


# I use this code to label a graph with the R2:

# graph
x - rnorm(100)
y - x + rnorm(100)
lm1 - lm(y~x)
plot(x,y)

# label
R2text - substitute(paste(R^2, = ,r2),list(r2=r2)) text(1,-3,R2text,
col=red)

# i have modified this a bit, so that i have a vector with other labels,
each of which # will be labelled on the graph. Example:
texts - c(And the R2 is, R2text)
x - c(-2,-2)
y - c(2,1)
for(i in 1:length(texts))text(x[i],y[i],texts[i],pos=4, col=blue)

# As you can see the label R2 = 48.7 remains at paste(R^2,  = ,
48.7)
# What to do?



Thanks for your help,

Remko



..-~-.-~-.-~-.-~-.-~-.-~-.-~-.-~-.-~-
Remko Duursma
Post-doctoral researcher
Dept. Forest Ecology
University of Helsinki, Finland

_
With tax season right around the corner, make sure to follow these few
simple tips.

__
R-help@stat.math.ethz.ch 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@stat.math.ethz.ch 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.


Re: [R] substitute question

2004-03-20 Thread Peter Dalgaard
Tony Plate [EMAIL PROTECTED] writes:

 Earlier in this discussion, Peter Dalgard stated you can only do
 substitutions on language objects and then used the function
 is.language() in an example, which I took at that time to imply that
 substitute() would go inside objects for which is.language() returned
 true.  However, from experimenting, it seems that is.call() rather
 than is.language() is the appropriate test.

Right. That surprised me too, although perhaps it shouldn't have. Of
course we might just have looked at the source, where we see that
PROMSXP, SYMSXP, and LANGSXP are handled, and everything else,
including EXPRSXPs are returned as is. I think this is deliberate and
that expression objects are occasionally used as a quoting mechanism
to prevent substitutions from taking place, but my recollection is a
bit hazy on this point. So at the R level it is is.name() or is.call()
or promises evaluating to either of the two.

Notice, BTW, that expression() is weird in the same way as
the function(...)... constructs that tripped Gabor:

 substitute(expression(a+b),list(b=2))
expression(a + 2)
 eval(substitute(substitute(e,list(b=2)), list(e=expression(a+b
expression(a + b)
 eval(substitute(substitute(e,list(b=2)), list(e=quote(expression(a+b)
expression(a + 2)

and the root cause of this is that  

 expression(a+b)
expression(a + b)
 quote(expression(a+b))
expression(a + b)

There's a group of cases where deparse and parse are not exact
inverses, because some objects are not directly representable in the
language, so you get instead a function call that *evaluates* to a
similar object; the simplest case is vectors of length  1:

 dput(rnorm(1))
-0.214713202300464
 dput(rnorm(2))
c(0.92727004398074, 0.437854016853309)


-- 
   O__   Peter Dalgaard Blegdamsvej 3  
  c/ /'_ --- Dept. of Biostatistics 2200 Cph. N   
 (*) \(*) -- University of Copenhagen   Denmark  Ph: (+45) 35327918
~~ - ([EMAIL PROTECTED]) FAX: (+45) 35327907

__
[EMAIL PROTECTED] 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


Re: [R] substitute question

2004-03-19 Thread Gabor Grothendieck

[This appears to have bounced so I am sending it again.  Apologies
if it gets there twice.]

Thanks. Thus it seems that there are two types of expressions and calls:

1. fully expanded 
2. partially expanded

and that fully expanded ones are a prerequisite for substitution.
body() and quote() produce such fully expanded expressions.

Using a small utility function we can investigate this:

recurse - function( x, idx = NULL )
 if ( length( x )  0 ) { 
  for( i in seq( along = x ) )
   if (length(x[[i]])1) 
Recall( x[[i]], c(idx, i))
   else {
if (length(idx)) cat(idx,)
cat( i, class(x[[i]]), : )
cat( rep(\t,length(idx) + 2) )
print( x[[i]] )
   }
 }

f - function(){a+1}

eb - body(f)
class(eb)
recurse(eb)

eq - quote(function(){a+1})
class(eq)
recurse(eq)

ep - parse(text=deparse(f))
class(ep)
recurse(ep)


The output that the above is shown below. It shows that
body() and quote() produce fully expanded expression style objects
although body's is of class { and quote is of class call.

However, parse(text=deparse(f)) also produces a fully expanded
expression style object of class expression yet substitution 
does not occur with that. Thus full vs. partial expansion is likely
a necessary but not a sufficient condition. There is something
else but I don't know what it is.


 f - function(){a+1}
 
 eb - body(f)
 class(eb)
[1] {
 recurse(eb)
1 name : `{`
2 1 name : `+`
2 2 name : a
2 3 numeric : [1] 1
 
 eq - quote(function(){a+1})
 class(eq)
[1] call
 recurse(eq) # lines begin with list indices and class name
1 name : `function`
2 NULL : NULL
3 1 name : `{`
3 2 1 name : `+`
3 2 2 name : a
3 2 3 numeric : [1] 1
4 NULL : NULL
 
 ep - parse(text=deparse(f))
 class(ep)
[1] expression
 recurse(ep)
1 1 name : `function`
1 2 NULL : NULL
1 3 1 name : `{`
1 3 2 1 name : `+`
1 3 2 2 name : a
1 3 2 3 numeric : [1] 1
1 4 NULL : NULL


Date: Thu, 18 Mar 2004 17:27:20 -0800 (PST) 
From: Thomas Lumley [EMAIL PROTECTED]
To: Gabor Grothendieck [EMAIL PROTECTED] 
Cc: [EMAIL PROTECTED], [EMAIL PROTECTED] 
Subject: Re: [R] substitute question 


On Thu, 18 Mar 2004, Gabor Grothendieck wrote:



 I don't think I expressed myself very well on that.

 Looking at what we get from the example:

  z - substitute(substitute(expression(f),list(a=quote(b))),list(f=f))

  z
 substitute(expression(function ()
 {
 a + 1
 }), list(a = quote(b)))

  class(z);mode(z);typeof(z)
 [1] call
 [1] call
 [1] language


 we see that the function seems to be expanded correctly and
 the statement does produce a call object. However,
 applying eval one, two or three times does not give what
 you would think if you looked at z above.

Maybe we didn't express ourselves well enough.

Looking at z above isn't enough. z is a call to substitute().
Its first operand is an expression. The expression contains a single term,
which is a function.

If you typed
notz- quote(substitute(expression(function ()
{
a + 1
}), list(a = quote(b

you would obtain something that deparsed the same as z, and so looked the
same, but was actually different. In notz the first operand of substitute
is an expression containing multiple terms, which if evaluated would
return a function.

substitute() goes though this expression and checks each term to see if it
is `a`. In z there is only one term and it isn't `a`. In notz there is
(after sufficient recursion) an `a` and it gets replaced.

So

 z[[2]][[2]]
function ()
{
a + 1
}
 notz[[2]][[2]]
function() {
a + 1
}

are the respective operands, and they still look the same. But

 mode(z[[2]][[2]])
[1] function
 mode(notz[[2]][[2]])
[1] call
 length(z[[2]][[2]])
[1] 1
 length(notz[[2]][[2]])
[1] 4

and if we try to find the actual `a` in there
 notz[[2]][[2]][[3]][[2]][[2]]
a
 z[[2]][[2]][[3]][[2]][[2]]
Error in z[[2]][[2]][[3]] : object is not subsettable



-thomas

__
[EMAIL PROTECTED] 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


Re: [R] substitute question

2004-03-19 Thread Gabor Grothendieck


Great detective work, Tony!  Thanks.

Date:   Fri, 19 Mar 2004 17:51:27 -0700 
From:   Tony Plate [EMAIL PROTECTED]
To:   [EMAIL PROTECTED], [EMAIL PROTECTED] 
Cc:   [EMAIL PROTECTED] 
Subject:   Re: [R] substitute question 

 
I don't think it is correct that there are two types of expressions and 
calls. There is only one type of these things. I believe the relevant 
distinction here is between 'call' objects (which can be informally thought 
of as the parse trees of unevaluated R code, and which formally have mode 
'call' in R) and other things like objects of mode 'function', etc.

However, this is all does pretty confusing when using substitute(), 
because, substitute() does go inside objects that have mode 'call', but 
doesn't go inside of objects that have mode 'function' or 
'expression'. What makes it more confusing is that sometimes 'call' 
objects can be wrapped up in expression objects. Note that parse(text=) 
returns a 'call' object wrapped in an 'expression' object, whereas quote() 
returns a 'call' object -- I believe that in general it is true that 
parse(text=XXX)[[1]] === quote(XXX).

Earlier in this discussion, Peter Dalgard stated you can only do 
substitutions on language objects and then used the function is.language() 
in an example, which I took at that time to imply that substitute() would 
go inside objects for which is.language() returned true. However, from 
experimenting, it seems that is.call() rather than is.language() is the 
appropriate test.

Here are some simple examples.

 esub - function(expr, sublist) do.call(substitute, list(expr, sublist))
 e1 - parse(text=a + 1)
 e2 - quote(a + 1)
 e1
expression(a + 1)
 e2
a + 1
 mode(e1)
[1] expression
 mode(e2)
[1] call
 identical(e1[[1]], e2)
[1] TRUE

 # substitute() doesn't go inside e1, even though is.language(e1) is TRUE
 c(is.language(e1), is.call(e1))
[1] TRUE FALSE
 esub(e1, list(a=as.name('b')))
expression(a + 1)

 c(is.language(e2), is.call(e2))
[1] TRUE TRUE
 esub(e2, list(a=as.name('b')))
b + 1

 c(is.language(e1[[1]]), is.call(e1[[1]]))
[1] TRUE TRUE
 esub(e1[[1]], list(a=as.name('b')))
b + 1
 identical(e2, e1[[1]])
[1] TRUE

 ef - Quote(function() a + 1)
 f - function() a + 1
 c(is.language(ef), is.call(ef))
[1] TRUE TRUE
 esub(ef, list(a=as.name('b')))
function() b + 1
 c(is.language(f), is.call(f))
[1] FALSE FALSE
 esub(f, list(a=as.name('b')))
function ()
a + 1
 c(is.language(body(f)), is.call(body(f)))
[1] TRUE TRUE
 esub(body(f), list(a=as.name('b')))
b + 1



I also see that in S-plus 6.2, substitute() behaves differently -- it does 
go inside objects of mode 'call' and 'expression' and substitutes 'b' for 
'a' in every case above. To run the above code in S-plus, first do:
 body - function(f) f[[1]]
 quote - Quote

Although there isn't much to guide one in the documentation ?substitute, 
the R Language manual does have some discussion of substitute() and 
'expression' objects.

-- Tony Plate

At Thursday 10:58 PM 3/18/2004, Gabor Grothendieck wrote:

Thanks. Thus it seems that there are two types of expressions and calls:

1. fully expanded
2. partially expanded

and that fully expanded ones are a prerequisite for substitution.
body() and quote() produce such fully expanded expressions.

Using a small utility function we can investigate this:

recurse - function( x, idx = NULL )
 if ( length( x )  0 ) {
 for( i in seq( along = x ) )
 if (length(x[[i]])1)
 Recall( x[[i]], c(idx, i))
 else {
 if (length(idx)) cat(idx,)
 cat( i, class(x[[i]]), : )
 cat( rep(\t,length(idx) + 2) )
 print( x[[i]] )
 }
 }

f - function(){a+1}

eb - body(f)
class(eb)
recurse(eb)

eq - quote(function(){a+1})
class(eq)
recurse(eq)

ep - parse(text=deparse(f))
class(ep)
recurse(ep)


The output that the above is shown below. It shows that
body() and quote() produce fully expanded expression style objects
although body's is of class { and quote is of class call.

However, parse(text=deparse(f)) also produces a fully expanded
expression style object of class expression yet substitution
does not occur with that. Thus full vs. partial expansion is likely
a necessary but not a sufficient condition. There is something
else but I don't know what it is.


  f - function(){a+1}
 
  eb - body(f)
  class(eb)
[1] {
  recurse(eb)
1 name : `{`
2 1 name : `+`
2 2 name : a
2 3 numeric : [1] 1
 
  eq - quote(function(){a+1})
  class(eq)
[1] call
  recurse(eq) # lines begin with list indices and class name
1 name : `function`
2 NULL : NULL
3 1 name : `{`
3 2 1 name : `+`
3 2 2 name : a
3 2 3 numeric : [1] 1
4 NULL : NULL
 
  ep - parse(text=deparse(f))
  class(ep)
[1] expression
  recurse(ep)
1 1 name : `function`
1 2 NULL : NULL
1 3 1 name : `{`
1 3 2 1 name : `+`
1 3 2 2 name : a
1 3 2 3 numeric : [1] 1
1 4 NULL : NULL


Date: Thu, 18 Mar 2004 17:27:20 -0800 (PST)
From: Thomas Lumley [EMAIL PROTECTED]
To: Gabor Grothendieck [EMAIL PROTECTED]
Cc: [EMAIL PROTECTED], [EMAIL PROTECTED]
Subject: Re: [R] substitute question


On Thu, 18 Mar 2004, Gabor

RE: [R] substitute question

2004-03-18 Thread Thomas Lumley
On Wed, 17 Mar 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}


Interesting.

Appearances are misleading, however:
 z - substitute( function(){a+1}, list(a=quote(b)) )
 z
function() {
b + 1
}
 f-eval(z)
 f()
Error in f() : Object b not found
 f
function(){a+1}
 attr(f,source)-NULL
 f
function ()
{
b + 1
}

So it isn't that eval(z) has a+1 inside, it just has a source attribute
with a+1.

Looking more carefully at z
 as.list(z)
[[1]]
`function`

[[2]]
NULL

[[3]]
{
b + 1
}

[[4]]
[1] function(){a+1}

so the original construction of z has kept the source (not, however, as a
source attribute).

There is method to our madness here.  It is impossible (or at least too
complicated) to keep comments in the right place as a function is
parsed and deparsed.  In the old days, comments would occasionally move
around, sometimes in very misleading ways (IIRC with if(){}else{} cases)

Now we keep a copy of the source code with functions created interactively
or with source(), and drop the comments on parsing.  This is controlled by
options(keep.source).

If you do a lot of substitute()-style programming you may want
options(keep.source=FALSE).

-thomas

PS: There are, of course, interesting possibilities for creative abuse of
the source attribute

__
[EMAIL PROTECTED] 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


RE: [R] substitute question

2004-03-18 Thread Tony Plate
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: [EMAIL PROTECTED], Peter Dalgaard [EMAIL PROTECTED]
From: Tony Plate [EMAIL PROTECTED]
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 [EMAIL PROTECTED]
[ Add to Address Book | Block Address | Report as Spam ]
To:   [EMAIL PROTECTED]
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?

__
[EMAIL PROTECTED] 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
__
[EMAIL PROTECTED] 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


RE: [R] substitute question

2004-03-18 Thread Gabor Grothendieck

Tony, Thomas.  Thanks for your help.  Your comments were very
useful.

Unfortunately, my next step gives me a new round of problems.

The following is the same as the last example except that instead
of hard coding the function into the expression I wanted to 
pass it to the expression.  It seems like one has to do a double
substitute to get this effect but I am having problems getting this
to work.

In the code below we first show that the keep.source option has been
set to FALSE so that the source attribute does not mislead us.

Then we do a double substitute.  The outer substitute just creates
the substitute that was in my previous question.  This outer
substitute produces z, a call object.  So far its as expected.

We then do ze - eval(z) but we get a function object right away.  I was
expecting that we get an expression object.  Even worse, the function does not
have  a  replaced with  b -- even though this did work in the previous example 
that I posted.  

What's wrong?


 options()$keep.source
[1] FALSE
 f - function(){a+1}
 z - substitute(substitute(f,list(a=quote(b))),list(f=f))
 class(z)
[1] call
 as.list(z)
[[1]]
substitute

[[2]]
function () 
{
a + 1
}

[[3]]
list(a = quote(b))

 ze - eval(z)
 class(ze)
[1] function
 ze
function () 
{
a + 1
}
 attr(ze,source)
NULL
 

---

Date:   Thu, 18 Mar 2004 09:00:02 -0800 (PST) 
From:   Thomas Lumley [EMAIL PROTECTED]
To:   Gabor Grothendieck [EMAIL PROTECTED] 
Cc:   [EMAIL PROTECTED] 
Subject:   RE: [R] substitute question 

 
On Wed, 17 Mar 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}


Interesting.

Appearances are misleading, however:
 z - substitute( function(){a+1}, list(a=quote(b)) )
 z
function() {
b + 1
}
 f-eval(z)
 f()
Error in f() : Object b not found
 f
function(){a+1}
 attr(f,source)-NULL
 f
function ()
{
b + 1
}

So it isn't that eval(z) has a+1 inside, it just has a source attribute
with a+1.

Looking more carefully at z
 as.list(z)
[[1]]
`function`

[[2]]
NULL

[[3]]
{
b + 1
}

[[4]]
[1] function(){a+1}

so the original construction of z has kept the source (not, however, as a
source attribute).

There is method to our madness here. It is impossible (or at least too
complicated) to keep comments in the right place as a function is
parsed and deparsed. In the old days, comments would occasionally move
around, sometimes in very misleading ways (IIRC with if(){}else{} cases)

Now we keep a copy of the source code with functions created interactively
or with source(), and drop the comments on parsing. This is controlled by
options(keep.source).

If you do a lot of substitute()-style programming you may want
options(keep.source=FALSE).

 -thomas

PS: There are, of course, interesting possibilities for creative abuse of
the source attribute

---

Date:   Thu, 18 Mar 2004 08:41:54 -0700 
From:   Tony Plate [EMAIL PROTECTED]
To:   [EMAIL PROTECTED], [EMAIL PROTECTED] 
Subject:   RE: [R] substitute question 

 
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: [EMAIL PROTECTED], Peter Dalgaard [EMAIL PROTECTED]
From: Tony Plate [EMAIL PROTECTED]
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

RE: [R] substitute question

2004-03-18 Thread Tony Plate
Gabor, I suspect you are overlooking the fact that substitute() does not 
evaluate its first argument.  So, in the previous example you were giving 
an unevaluated expression as the first argument of substitute().  In your 
most recent example you are supplying a function object as the first 
argument of substitute() (by supplying it as the value to be substituted 
for f).  I think you can get what you want by first doing f - 
Quote(function(){a+1}):

 f - Quote(function(){a+1})
 f
function() {
a + 1
}
 z - substitute(substitute(f,list(a=quote(b))),list(f=f))
 z
substitute(function() {
a + 1
}, list(a = quote(b)))
 eval(z)
function() {
b + 1
}
 eval(eval(z)) # this displays the source attribute
function(){a+1}
 body(eval(eval(z)))
{
b + 1
}

hope this helps,

Tony Plate

At Thursday 12:00 PM 3/18/2004, you wrote:

Tony, Thomas.  Thanks for your help.  Your comments were very
useful.
Unfortunately, my next step gives me a new round of problems.

The following is the same as the last example except that instead
of hard coding the function into the expression I wanted to
pass it to the expression.  It seems like one has to do a double
substitute to get this effect but I am having problems getting this
to work.
In the code below we first show that the keep.source option has been
set to FALSE so that the source attribute does not mislead us.
Then we do a double substitute.  The outer substitute just creates
the substitute that was in my previous question.  This outer
substitute produces z, a call object.  So far its as expected.
We then do ze - eval(z) but we get a function object right away.  I was
expecting that we get an expression object.  Even worse, the function does not
have  a  replaced with  b -- even though this did work in the previous 
example
that I posted.

What's wrong?

 options()$keep.source
[1] FALSE
 f - function(){a+1}
 z - substitute(substitute(f,list(a=quote(b))),list(f=f))
 class(z)
[1] call
 as.list(z)
[[1]]
substitute
[[2]]
function ()
{
a + 1
}
[[3]]
list(a = quote(b))
 ze - eval(z)
 class(ze)
[1] function
 ze
function ()
{
a + 1
}
 attr(ze,source)
NULL

---

Date:   Thu, 18 Mar 2004 09:00:02 -0800 (PST)
From:   Thomas Lumley [EMAIL PROTECTED]
To:   Gabor Grothendieck [EMAIL PROTECTED]
Cc:   [EMAIL PROTECTED]
Subject:   RE: [R] substitute question
On Wed, 17 Mar 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}
Interesting.

Appearances are misleading, however:
 z - substitute( function(){a+1}, list(a=quote(b)) )
 z
function() {
b + 1
}
 f-eval(z)
 f()
Error in f() : Object b not found
 f
function(){a+1}
 attr(f,source)-NULL
 f
function ()
{
b + 1
}
So it isn't that eval(z) has a+1 inside, it just has a source attribute
with a+1.
Looking more carefully at z
 as.list(z)
[[1]]
`function`
[[2]]
NULL
[[3]]
{
b + 1
}
[[4]]
[1] function(){a+1}
so the original construction of z has kept the source (not, however, as a
source attribute).
There is method to our madness here. It is impossible (or at least too
complicated) to keep comments in the right place as a function is
parsed and deparsed. In the old days, comments would occasionally move
around, sometimes in very misleading ways (IIRC with if(){}else{} cases)
Now we keep a copy of the source code with functions created interactively
or with source(), and drop the comments on parsing. This is controlled by
options(keep.source).
If you do a lot of substitute()-style programming you may want
options(keep.source=FALSE).
 -thomas

PS: There are, of course, interesting possibilities for creative abuse of
the source attribute
---

Date:   Thu, 18 Mar 2004 08:41:54 -0700
From:   Tony Plate [EMAIL PROTECTED]
To:   [EMAIL PROTECTED], [EMAIL PROTECTED]
Subject:   RE: [R] substitute question
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: [EMAIL PROTECTED], Peter Dalgaard [EMAIL PROTECTED]
From: Tony Plate [EMAIL PROTECTED]
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

RE: [R] substitute question

2004-03-18 Thread Thomas Lumley
On Thu, 18 Mar 2004, Gabor Grothendieck wrote:


 Tony, Thomas.  Thanks for your help.  Your comments were very
 useful.

 Unfortunately, my next step gives me a new round of problems.

 The following is the same as the last example except that instead
 of hard coding the function into the expression I wanted to
 pass it to the expression.  It seems like one has to do a double
 substitute to get this effect but I am having problems getting this
 to work.


The problem is that f is a function, not an expression. You need to work
with body(f)

Either
 f-function(){a+1}
body(f)-do.call(substitute,list(body(f),list(a=quote(b f
function ()
{
b + 1
}

or
 f-function(){a+1}
 body(f)-eval(substitute(substitute(expr,list(a=quote(b))),list(expr=body(f
 f
function ()
{
b + 1
}


-thomas

__
[EMAIL PROTECTED] 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


RE: [R] substitute question

2004-03-18 Thread Leonard Assis
 Anyone Knows How Shoud I Build Rasch Models (Partial Credit Models)
In R?


[]s
Leonard Assis
Estatístico - CONFE 7439

__
[EMAIL PROTECTED] 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


RE: [R] substitute question

2004-03-18 Thread Gabor Grothendieck


Tony, Thomas,  Thanks, again.

If the problem with my last example was just that I was passing a function
rather than an unevaluated expression, then why don't the following 
return f with b in place of a?  In both cases, a is still there in the
final output.

f - function() { a + 1 }
z - substitute(substitute(f=f,list(a=quote(b))),list(f=parse(text=deparse(f
eval(eval(z))

or

f - function() { a + 1 }
z - substitute(substitute(expression(f),list(a=quote(b))),list(f=f))
eval(eval(eval(z)))

---

Date:   Thu, 18 Mar 2004 11:29:39 -0800 (PST) 
From:   Thomas Lumley [EMAIL PROTECTED]
To:   Gabor Grothendieck [EMAIL PROTECTED] 
Cc:   [EMAIL PROTECTED], [EMAIL PROTECTED] 
Subject:   RE: [R] substitute question 

 
On Thu, 18 Mar 2004, Gabor Grothendieck wrote:


 Tony, Thomas. Thanks for your help. Your comments were very
 useful.

 Unfortunately, my next step gives me a new round of problems.

 The following is the same as the last example except that instead
 of hard coding the function into the expression I wanted to
 pass it to the expression. It seems like one has to do a double
 substitute to get this effect but I am having problems getting this
 to work.


The problem is that f is a function, not an expression. You need to work
with body(f)

Either
 f-function(){a+1}
body(f)-do.call(substitute,list(body(f),list(a=quote(b f
function ()
{
b + 1
}

or
 f-function(){a+1}
 body(f)-eval(substitute(substitute(expr,list(a=quote(b))),list(expr=body(f
 f
function ()
{
b + 1
}


 -thomas

---

Date:   Thu, 18 Mar 2004 12:15:45 -0700 
From:   Tony Plate [EMAIL PROTECTED]
To:   [EMAIL PROTECTED] 
Cc:   [EMAIL PROTECTED] 
Subject:   RE: [R] substitute question 

 
Gabor, I suspect you are overlooking the fact that substitute() does not 
evaluate its first argument. So, in the previous example you were giving 
an unevaluated expression as the first argument of substitute(). In your 
most recent example you are supplying a function object as the first 
argument of substitute() (by supplying it as the value to be substituted 
for f). I think you can get what you want by first doing f - 
Quote(function(){a+1}):

 f - Quote(function(){a+1})
 f
function() {
a + 1
}
 z - substitute(substitute(f,list(a=quote(b))),list(f=f))
 z
substitute(function() {
a + 1
}, list(a = quote(b)))
 eval(z)
function() {
b + 1
}
 eval(eval(z)) # this displays the source attribute
function(){a+1}
 body(eval(eval(z)))
{
b + 1
}


hope this helps,

Tony Plate

At Thursday 12:00 PM 3/18/2004, you wrote:

Tony, Thomas. Thanks for your help. Your comments were very
useful.

Unfortunately, my next step gives me a new round of problems.

The following is the same as the last example except that instead
of hard coding the function into the expression I wanted to
pass it to the expression. It seems like one has to do a double
substitute to get this effect but I am having problems getting this
to work.

In the code below we first show that the keep.source option has been
set to FALSE so that the source attribute does not mislead us.

Then we do a double substitute. The outer substitute just creates
the substitute that was in my previous question. This outer
substitute produces z, a call object. So far its as expected.

We then do ze - eval(z) but we get a function object right away. I was
expecting that we get an expression object. Even worse, the function does not
have a replaced with b -- even though this did work in the previous 
example
that I posted.

What's wrong?


  options()$keep.source
[1] FALSE
  f - function(){a+1}
  z - substitute(substitute(f,list(a=quote(b))),list(f=f))
  class(z)
[1] call
  as.list(z)
[[1]]
substitute

[[2]]
function ()
{
 a + 1
}

[[3]]
list(a = quote(b))

  ze - eval(z)
  class(ze)
[1] function
  ze
function ()
{
 a + 1
}
  attr(ze,source)
NULL
 

---

Date: Thu, 18 Mar 2004 09:00:02 -0800 (PST)
From: Thomas Lumley [EMAIL PROTECTED]
To: Gabor Grothendieck [EMAIL PROTECTED]
Cc: [EMAIL PROTECTED]
Subject: RE: [R] substitute question


On Wed, 17 Mar 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}


Interesting.

Appearances are misleading, however:
  z - substitute( function(){a+1}, list(a=quote(b)) )
  z
function() {
b + 1
}
  f-eval(z)
  f()
Error in f() : Object b not found
  f
function(){a+1}
  attr(f,source)-NULL
  f
function ()
{
b + 1
}

So it isn't that eval(z) has a+1 inside, it just has a source attribute
with a+1.

Looking more carefully at z
  as.list(z)
[[1]]
`function`

[[2]]
NULL

[[3]]
{
b + 1
}

[[4]]
[1] function(){a+1}

so the original construction of z has kept the source (not, however, as a
source attribute).

There is method to our madness here. It is impossible (or at least too
complicated) to keep comments in the right place as a function is
parsed

Re: [R] substitute question

2004-03-18 Thread Peter Dalgaard
Gabor Grothendieck [EMAIL PROTECTED] writes:

 Tony, Thomas,  Thanks, again.
 
 If the problem with my last example was just that I was passing a function
 rather than an unevaluated expression, then why don't the following 
 return f with b in place of a?  In both cases, a is still there in the
 final output.
 
 f - function() { a + 1 }
 z - substitute(substitute(f=f,list(a=quote(b))),list(f=parse(text=deparse(f
 eval(eval(z))
 
 or
 
 f - function() { a + 1 }
 z - substitute(substitute(expression(f),list(a=quote(b))),list(f=f))
 eval(eval(eval(z)))

As far as I can see you don't quote *the expression that creates f* in
either of the above

f - quote(function() { a + 1 })
attr(f,source) - NULL
g - eval(substitute(substitute(f, list(a=quote(b))),list(f=f)))
g
g() # oops, g is not a function but a call to function
g - eval(g)
b - 500
g()

If you have only the function to begin with, try something along these
lines 

f - function() { a + 1 }
g - f
attr(g,source) - NULL
body(g) - eval(substitute(substitute(f, list(a=quote(b))),list(f=body(f
g
g()


(The real pain in these examples is that substitute autoquotes its
expr argument. Therefore, when you want to modify an expression that
is already stored in a variable, you need an extra outer layer of
eval(substitute(...)) to poke the content of the variable into the
inner substitute. An esub function  with standard evaluation
semantics would make this much easier.)

-- 
   O__   Peter Dalgaard Blegdamsvej 3  
  c/ /'_ --- Dept. of Biostatistics 2200 Cph. N   
 (*) \(*) -- University of Copenhagen   Denmark  Ph: (+45) 35327918
~~ - ([EMAIL PROTECTED]) FAX: (+45) 35327907

__
[EMAIL PROTECTED] 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


Re: [R] substitute question

2004-03-18 Thread Gabor Grothendieck


From:   Peter Dalgaard [EMAIL PROTECTED]
 (The real pain in these examples is that substitute autoquotes its
 expr argument. Therefore, when you want to modify an expression that
 is already stored in a variable, you need an extra outer layer of
 eval(substitute(...)) to poke the content of the variable into the
 inner substitute. An esub function with standard evaluation
 semantics would make this much easier.)

That is one of the frustrations of using substitute.  

The other is that even if you do perform two levels of substitute,
as I have been trying, you still can't count on it working for
an arbitrary unevaluated expression, as my examples show.  

Even putting aside the source attribute which is super confusing
until you know about it, all the solutions that I can see to 
the problem I presented are ugly.

(1) One can either pick apart the function using body, or 

(2) I  assume one could convert the function to text and 
paste together the correct substitute command with the text of 
the function inserted in its argument.   

The quote mechanism works but is not applicable if all you have
is the function itself (as you point out).

This is sooo frustrating.

Thanks to you, Tony and Thomas for all your help.

__
[EMAIL PROTECTED] 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


Re: [R] substitute question

2004-03-18 Thread Peter Dalgaard
Gabor Grothendieck [EMAIL PROTECTED] writes:

 From:   Peter Dalgaard [EMAIL PROTECTED]
  (The real pain in these examples is that substitute autoquotes its
  expr argument. Therefore, when you want to modify an expression that
  is already stored in a variable, you need an extra outer layer of
  eval(substitute(...)) to poke the content of the variable into the
  inner substitute. An esub function with standard evaluation
  semantics would make this much easier.)
 
 That is one of the frustrations of using substitute.  
 
 The other is that even if you do perform two levels of substitute,
 as I have been trying, you still can't count on it working for
 an arbitrary unevaluated expression, as my examples show.  

Er, I don't think so. All I have seen is a couple of cases where you
tried to pass something that was not a language object (e.g. a
function as opposed to an expression or call generating a function.)

 Even putting aside the source attribute which is super confusing
 until you know about it, all the solutions that I can see to 
 the problem I presented are ugly.
 
 (1) One can either pick apart the function using body, or 
 
 (2) I  assume one could convert the function to text and 
 paste together the correct substitute command with the text of 
 the function inserted in its argument.   
 
 The quote mechanism works but is not applicable if all you have
 is the function itself (as you point out).
 
 This is sooo frustrating.

Well, the certain road to frustration is to try to do the impossible.
A function is not a language object and you can only do substitutions
on language objects.

 f - function()x
 g - quote(function()x)
 f
function()x
 g
function() x
 mode(f)
[1] function
 mode(g)
[1] call
 is.language(f)
[1] FALSE
 is.language(g)
[1] TRUE

However, a function is basically a triplet consisting of an argument
list, a body, and an environment, the middle of which *is* a language
object. So I don't think your (1) is ugly, it's the logical way to
proceed. 

-- 
   O__   Peter Dalgaard Blegdamsvej 3  
  c/ /'_ --- Dept. of Biostatistics 2200 Cph. N   
 (*) \(*) -- University of Copenhagen   Denmark  Ph: (+45) 35327918
~~ - ([EMAIL PROTECTED]) FAX: (+45) 35327907

__
[EMAIL PROTECTED] 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


Re: [R] substitute question

2004-03-18 Thread Gabor Grothendieck

 Date:   18 Mar 2004 23:52:47 +0100 
 From:   Peter Dalgaard [EMAIL PROTECTED]
 To:   [EMAIL PROTECTED] 
 Cc:   [EMAIL PROTECTED], [EMAIL PROTECTED], [EMAIL PROTECTED], [EMAIL 
 PROTECTED] 
 Subject:   Re: [R] substitute question 
 
  
 Gabor Grothendieck [EMAIL PROTECTED] writes:
 
  From: Peter Dalgaard [EMAIL PROTECTED]
   (The real pain in these examples is that substitute autoquotes its
   expr argument. Therefore, when you want to modify an expression that
   is already stored in a variable, you need an extra outer layer of
   eval(substitute(...)) to poke the content of the variable into the
   inner substitute. An esub function with standard evaluation
   semantics would make this much easier.)
  
  That is one of the frustrations of using substitute. 
  
  The other is that even if you do perform two levels of substitute,
  as I have been trying, you still can't count on it working for
  an arbitrary unevaluated expression, as my examples show. 
 
 Er, I don't think so. All I have seen is a couple of cases where you
 tried to pass something that was not a language object (e.g. a
 function as opposed to an expression or call generating a function.)
 
 

The parse/deparse one definitely is an expression:

 z - parse(text=deparse(f))
 class(z);mode(z);typeof(z)
[1] expression
[1] expression
[1] expression

In the other one, it is not an expression in the inner substitute
but should be by the time it gets to the outer one since I
explicitly added expression(...).  It is expanded which shows
it did do that part right.

__
[EMAIL PROTECTED] 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


Re: [R] substitute question

2004-03-18 Thread Tony Plate
Gabor, you might have less frustration if you work with Peter's esub() 
suggestion (use it instead of substitute()):

esub - function(expr, subst.list) do.call(substitute, list(expr, 
subst.list))

When you say

In the other one, it is not an expression in the inner substitute
but should be by the time it gets to the outer one since I explicitly added 
expression(...).  It is expanded which shows it did do that part right.

something to bear in mind is the natural order of evaluation is reversed 
with nested substitute()'s (because the inner substitute() is quoted by the 
outer substitute())  (but I haven't carefully reasoned through this being 
an explanation for your particular frustration here.)

hope this might help,

Tony Plate



At Thursday 04:06 PM 3/18/2004, Gabor Grothendieck wrote:

 Date:   18 Mar 2004 23:52:47 +0100
 From:   Peter Dalgaard [EMAIL PROTECTED]
 To:   [EMAIL PROTECTED]
 Cc:   [EMAIL PROTECTED], [EMAIL PROTECTED], 
[EMAIL PROTECTED], [EMAIL PROTECTED]
 Subject:   Re: [R] substitute question


 Gabor Grothendieck [EMAIL PROTECTED] writes:

  From: Peter Dalgaard [EMAIL PROTECTED]
   (The real pain in these examples is that substitute autoquotes its
   expr argument. Therefore, when you want to modify an expression that
   is already stored in a variable, you need an extra outer layer of
   eval(substitute(...)) to poke the content of the variable into the
   inner substitute. An esub function with standard evaluation
   semantics would make this much easier.)
 
  That is one of the frustrations of using substitute.
 
  The other is that even if you do perform two levels of substitute,
  as I have been trying, you still can't count on it working for
  an arbitrary unevaluated expression, as my examples show.

 Er, I don't think so. All I have seen is a couple of cases where you
 tried to pass something that was not a language object (e.g. a
 function as opposed to an expression or call generating a function.)



The parse/deparse one definitely is an expression:

 z - parse(text=deparse(f))
 class(z);mode(z);typeof(z)
[1] expression
[1] expression
[1] expression
In the other one, it is not an expression in the inner substitute
but should be by the time it gets to the outer one since I
explicitly added expression(...).  It is expanded which shows
it did do that part right.


___
No banners. No pop-ups. No kidding.
Introducing My Way - http://www.myway.com
__
[EMAIL PROTECTED] 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


Re: [R] substitute question

2004-03-18 Thread Thomas Lumley
On Thu, 18 Mar 2004, Gabor Grothendieck wrote:



 From:   Peter Dalgaard [EMAIL PROTECTED]
  (The real pain in these examples is that substitute autoquotes its
  expr argument. Therefore, when you want to modify an expression that
  is already stored in a variable, you need an extra outer layer of
  eval(substitute(...)) to poke the content of the variable into the
  inner substitute. An esub function with standard evaluation
  semantics would make this much easier.)

 That is one of the frustrations of using substitute.

 The other is that even if you do perform two levels of substitute,
 as I have been trying, you still can't count on it working for
 an arbitrary unevaluated expression, as my examples show.

You can, but a function isn't an arbitrary unevaluated expression
 You still aren't passing an expression containg the symbol `a`. You are
passing an expression containing the function f, whose body is an
expression containing the symbol `a`.  Functions aren't expressions.

 f - function() { a + 1 }
 z - substitute(substitute(f=f,list(a=quote(b))),list(f=parse(text=deparse(f)$
 eval(eval(z))

 or

 f - function() { a + 1 }
 z - substitute(substitute(expression(f),list(a=quote(b))),list(f=f))
 eval(eval(eval(z)))


 (1) One can either pick apart the function using body, or

Actually, I think this is fairly natural -- it is only body(f) that is an
expression.  Certainly substitute() could have been written to operate on
functions as well, but it wasn't.



-thomas

__
[EMAIL PROTECTED] 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


Re: [R] substitute question

2004-03-18 Thread Gabor Grothendieck


I don't think I expressed myself very well on that.  

Looking at what we get from the example:

 z - substitute(substitute(expression(f),list(a=quote(b))),list(f=f))

 z
substitute(expression(function () 
{
a + 1
}), list(a = quote(b)))

 class(z);mode(z);typeof(z)
[1] call
[1] call
[1] language


we see that the function seems to be expanded correctly and 
the statement does produce a call object.  However, 
applying eval one, two or three times does not give what 
you would think if you looked at z above.  In all cases, 
a is still there.  Some posters have claimed that the
problem is that list(f=f) cannot hold a function and must be
an expression but that's not what the help page says, the
examples are not all of class expression or call and
even if that were true then my parse/deparse example should 
work since it is unquestionably an expression.

Date:   Thu, 18 Mar 2004 16:41:31 -0700 
From:   Tony Plate [EMAIL PROTECTED]
To:   [EMAIL PROTECTED], [EMAIL PROTECTED] 
Cc:   [EMAIL PROTECTED], [EMAIL PROTECTED] 
Subject:   Re: [R] substitute question 

 
Gabor, you might have less frustration if you work with Peter's esub() 
suggestion (use it instead of substitute()):

esub - function(expr, subst.list) do.call(substitute, list(expr, 
subst.list))

When you say

In the other one, it is not an expression in the inner substitute
but should be by the time it gets to the outer one since I explicitly added 
expression(...). It is expanded which shows it did do that part right.

something to bear in mind is the natural order of evaluation is reversed 
with nested substitute()'s (because the inner substitute() is quoted by the 
outer substitute()) (but I haven't carefully reasoned through this being 
an explanation for your particular frustration here.)

hope this might help,

Tony Plate




At Thursday 04:06 PM 3/18/2004, Gabor Grothendieck wrote:

  Date: 18 Mar 2004 23:52:47 +0100
  From: Peter Dalgaard [EMAIL PROTECTED]
  To: [EMAIL PROTECTED]
  Cc: [EMAIL PROTECTED], [EMAIL PROTECTED], 
 [EMAIL PROTECTED], [EMAIL PROTECTED]
  Subject: Re: [R] substitute question
 
 
  Gabor Grothendieck [EMAIL PROTECTED] writes:
 
   From: Peter Dalgaard [EMAIL PROTECTED]
(The real pain in these examples is that substitute autoquotes its
expr argument. Therefore, when you want to modify an expression that
is already stored in a variable, you need an extra outer layer of
eval(substitute(...)) to poke the content of the variable into the
inner substitute. An esub function with standard evaluation
semantics would make this much easier.)
  
   That is one of the frustrations of using substitute.
  
   The other is that even if you do perform two levels of substitute,
   as I have been trying, you still can't count on it working for
   an arbitrary unevaluated expression, as my examples show.
 
  Er, I don't think so. All I have seen is a couple of cases where you
  tried to pass something that was not a language object (e.g. a
  function as opposed to an expression or call generating a function.)
 
 

The parse/deparse one definitely is an expression:

  z - parse(text=deparse(f))
  class(z);mode(z);typeof(z)
[1] expression
[1] expression
[1] expression

In the other one, it is not an expression in the inner substitute
but should be by the time it gets to the outer one since I
explicitly added expression(...). It is expanded which shows
it did do that part right.


__
[EMAIL PROTECTED] 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


Re: [R] substitute question

2004-03-18 Thread Gabor Grothendieck

Date:   Thu, 18 Mar 2004 15:56:59 -0800 (PST) 
From:   Thomas Lumley [EMAIL PROTECTED]
  
 On Thu, 18 Mar 2004, Gabor Grothendieck wrote:
  (1) One can either pick apart the function using body, or

 Actually, I think this is fairly natural -- it is only body(f) 
 that is an
 expression. Certainly substitute() could have been written to 
 operate on
 functions as well, but it wasn't.

In the context of R, natural is performing operations on whole
objects at once.  Its the same difference as indexing vs. vector
operations.

I am not sure where this came from about not operating on functions.
Are you sure?  I know just about everyone is saying this but
the help page does not refer to that and the 
example I gave where we do use list(f=f) for f a function does
seem to expand properly (see my last posting) although 
the subsitution never appears to take effect.

__
[EMAIL PROTECTED] 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


Re: [R] substitute question

2004-03-18 Thread Thomas Lumley
On Thu, 18 Mar 2004, Gabor Grothendieck wrote:



 I don't think I expressed myself very well on that.

 Looking at what we get from the example:

  z - substitute(substitute(expression(f),list(a=quote(b))),list(f=f))

  z
 substitute(expression(function ()
 {
 a + 1
 }), list(a = quote(b)))

  class(z);mode(z);typeof(z)
 [1] call
 [1] call
 [1] language


 we see that the function seems to be expanded correctly and
 the statement does produce a call object.  However,
 applying eval one, two or three times does not give what
 you would think if you looked at z above.

Maybe we didn't express ourselves well enough.

Looking at z above isn't enough.  z is a call to substitute().
Its first operand is an expression. The expression contains a single term,
which is a function.

If you typed
notz- quote(substitute(expression(function ()
 {
 a + 1
 }), list(a = quote(b

you would obtain something that deparsed the same as z, and so looked the
same, but was actually different.  In notz the first operand of substitute
is an expression containing multiple terms, which if evaluated would
return a function.

substitute() goes though this expression and checks each term to see if it
is `a`. In z there is only one term and it isn't `a`.  In notz there is
(after sufficient recursion) an `a` and it gets replaced.

So

 z[[2]][[2]]
function ()
{
a + 1
}
 notz[[2]][[2]]
function() {
a + 1
}

are the respective operands, and they still look the same. But

 mode(z[[2]][[2]])
[1] function
 mode(notz[[2]][[2]])
[1] call
 length(z[[2]][[2]])
[1] 1
 length(notz[[2]][[2]])
[1] 4

and if we try to find the actual `a` in there
 notz[[2]][[2]][[3]][[2]][[2]]
a
 z[[2]][[2]][[3]][[2]][[2]]
Error in z[[2]][[2]][[3]] : object is not subsettable



-thomas

__
[EMAIL PROTECTED] 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


Re: [R] substitute question

2004-03-18 Thread Thomas Lumley
On Thu, 18 Mar 2004, Gabor Grothendieck wrote:

 I am not sure where this came from about not operating on functions.
 Are you sure?  I know just about everyone is saying this but
 the help page does not refer to that and the
 example I gave where we do use list(f=f) for f a function does
 seem to expand properly (see my last posting) although
 the subsitution never appears to take effect.


Yes, I am sure.

It's not that it is invalid to have a function as the first argument of
substitute, it's that substitute() does not recurse into either the body
or the formal arguments of the function (or into the environment, though
no-one would expect that).


-thomas

__
[EMAIL PROTECTED] 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


[R] substitute question

2004-03-17 Thread Gabor Grothendieck




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?

__
[EMAIL PROTECTED] 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


RE: [R] substitute question

2004-03-17 Thread Gabor Grothendieck


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 [EMAIL PROTECTED]
[ Add to Address Book | Block Address | Report as Spam ] 
To:   [EMAIL PROTECTED] 
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?

__
[EMAIL PROTECTED] 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