[R] How to use current value of variable in function definition?

Nordlund, Dan (DSHS/RDA) NordlDJ at dshs.wa.gov
Fri Jul 3 01:50:25 CEST 2009


Alan,

Doesn't Peter Dalgaard's response get you what you originally asked for?  You said you wanted something like:

> if (1) { c <- 1; foo <- function () print(c); }
>c <- 2
>foo()

Based on Peter's email you could do

> c <- 1
> foo <- local({x <- c; function() print(x) })
> foo()
[1] 1
> c <- 2
> foo()
[1] 1

Hope this is helpful,

Dan

Daniel J. Nordlund
Washington State Department of Social and Health Services
Planning, Performance, and Accountability
Research and Data Analysis Division
Olympia, WA  98504-5204
 

> -----Original Message-----
> From: r-help-bounces at r-project.org [mailto:r-help-bounces at r-project.org] On
> Behalf Of William Dunlap
> Sent: Thursday, July 02, 2009 2:44 PM
> To: Allan Engelhardt
> Cc: r-help at r-project.org
> Subject: Re: [R] How to use current value of variable in function definition?
> 
> 
> 
> 
> ________________________________
> 
> 	From: Allan Engelhardt [mailto:allane at cybaea.com]
> 	Sent: Thursday, July 02, 2009 11:12 AM
> 	To: William Dunlap
> 	Cc: r-help at r-project.org
> 	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 at r-project.org
> 			[mailto:r-help-bounces at r-project.org] On Behalf
> Of Allan Engelhardt
> 			Sent: Thursday, July 02, 2009 9:47 AM
> 			To: r-help at r-project.org
> 			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 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.
> 
> 
> 
> 
> 	[[alternative HTML version deleted]]
> 
> ______________________________________________
> 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.




More information about the R-help mailing list