________________________________
From: Allan Engelhardt [mailto:all...@cybaea.com] Sent: Thursday, July 02, 2009 11:12 AM To: William Dunlap Cc: r-help@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-boun...@r-project.org [mailto:r-help-boun...@r-project.org] On Behalf Of Allan Engelhardt Sent: Thursday, July 02, 2009 9:47 AM To: r-help@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@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@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.