Author Login
Post Reply
________________________________
From: Allan Engelhardt [mailto:allane@(protected)]
Sent: Thursday, July 02, 2009 11:12 AM
To: William Dunlap
Cc: r-help@(protected)
Subject: Re: [R] How to use current value of variable in
function definition?
Thanks for the pointer to substitute(), William. This seems to
work and is a little shorter than yours:
a <- 1; foo <- eval(substitute(function () print(a),
env=list(a=a)))
a <- 2; foo()
# [1] 1
Not the clearest code I have ever seen, especially as 'foo'
still shows 'a':
print(foo)
# function () a
Allan
The need for eval and the misleading printout is why I sent the
longer version.
functionBody(foo) does show the right thing. One might consider
this a bug
in substitute(): it does not clear out the source information
when it works on
a call to function. You can add
attr(foo,"source")<-NULL
to fix up the printing.
substitute() doesn't seem to go into the default values of the
arguments,
which is where one might prefer to put variables like this.
The eval() around substitute() is needed because function(z)z+1
is a call to
a function called function, it is not a function until that call
gets evaluated
and substitute does not evaluate its first argument).
Using local() avoids these problems.
Bill Dunlap
TIBCO Software Inc - Spotfire Division
wdunlap tibco.com
On 02/07/09 18:28, William Dunlap wrote:
From: r-help-bounces@(protected)
[mailto:r-help-bounces@(protected)
Of Allan Engelhardt
Sent: Thursday, July 02, 2009 9:47 AM
To: r-help@(protected)
Subject: [R] How to use current value of
variable in function
definition?
Must be the heat or something but I can't get my
brain into gear and
figure out how to get something like
if (1) { c <- 1; foo <- function () print(c); }
c <- 2
foo()
to print 1, not 2. (The real life example is a
little more
complex, but
you get the idea. I don't want the variable c
in the function
definition, I want its value at that time.)
The only thing I have been able to come up with
is something like
if (1) foo <- (function () { c <- 1;
return(function () print(c)) })()
c <- 2
foo()
# [1] 1
You might try local(), as in
> c<-1 ; foo.local<-local({orig.c <- c ;
function()orig.c})
> foo.local()
[1] 1
> c<-3
> foo.local()
[1] 1
It is possible for someone to alter the orig.c after you
create
foo.local, as in
> assign("orig.c", 17, env=environment(foo.local))
> foo.local()
[1] 17
Looking at the function's code will not make it clear
where
orig.c is coming from. The clue is that its environment
is not
one of the standard named ones, but it given by a hex
number.
> foo.local
function()orig.c
<environment: 0x02108c54>
You could also use substitute() to change the code in
the function.
It can be messy to do but the resulting code may be
clearer (although
it won't give a hint as to where that constant came
from). E.g.,
> foo.substitute<-function()orig.c
> c<-1 ;
functionBody(foo.substitute)<-do.call(substitute,
list(functionBody(foo.substitute), list(orig.c=c)))
> foo.substitute()
[1] 1
> foo.substitute
function ()
1
Bill Dunlap
TIBCO Software Inc - Spotfire Division
wdunlap tibco.com
but that just hurts. Please make the pain go
away.
Can someone wake up my brain?
Allan.
______________________________________________
R-help@(protected)
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.
[[alternative HTML version deleted]]
______________________________________________
R-help@(protected)
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.