[Rd] Return function from function with minimal environment
Martin Maechler
maechler at stat.math.ethz.ch
Tue Apr 4 17:11:24 CEST 2006
>>>>> "Roger" == Roger D Peng <rpeng at jhsph.edu>
>>>>> on Tue, 04 Apr 2006 10:38:29 -0400 writes:
Roger> In R 2.3.0-to-be, I think you can do
Roger> foo <- function(huge) {
Roger> scale <- mean(huge)
Roger> g <- function(x) { scale * x }
Roger> environment(g) <- emptyenv()
Roger> g
Roger> }
yes, but for now, and for the given purpose,
also as seen in examples, such as splinefun() or approxfun(),
just rm() the things you don't want in the environment.
I.e.,
foo <- function(huge) {
scale <- mean(huge)
rm(huge)
function(x) { scale * x }
}
Martin
Roger> -roger
Roger> Henrik Bengtsson wrote:
>> Hi,
>>
>> this relates to the question "How to set a former environment?" asked
>> yesterday. What is the best way to to return a function with a
>> minimal environment from a function? Here is a dummy example:
>>
>> foo <- function(huge) {
>> scale <- mean(huge)
>> function(x) { scale * x }
>> }
>>
>> fcn <- foo(1:10e5)
>>
>> The problem with this approach is that the environment of 'fcn' does
>> not only hold 'scale' but also the memory consuming object 'huge',
>> i.e.
>>
>> env <- environment(fcn)
>> ll(envir=env) # ll() from R.oo
>> # member data.class dimension object.size
>> # 1 huge numeric 1000000 4000028
>> # 2 scale numeric 1 36
>>
>> save(env, file="temp.RData")
>> file.info("temp.RData")$size
>> # [1] 2007624
>>
>> I generate quite a few of these and my 'huge' objects are of order
>> 100Mb, and I want to keep memory usage as well as file sizes to a
>> minimum. What I do now, is to remove variable from the local
>> environment of 'foo' before returning, i.e.
>>
>> foo2 <- function(huge) {
>> scale <- mean(huge)
>> rm(huge)
>> function(x) { scale * x }
>> }
>>
>> fcn <- foo2(1:10e5)
>> env <- environment(fcn)
>> ll(envir=env)
>> # member data.class dimension object.size
>> # 1 scale numeric 1 36
>>
>> save(env, file="temp.RData")
>> file.info("temp.RData")$size
>> # [1] 156
>>
>> Since my "foo" functions are complicated and contains many local
>> variables, it becomes tedious to identify and remove all of them, so
>> instead I try:
>>
>> foo3 <- function(huge) {
>> scale <- mean(huge);
>> env <- new.env();
>> assign("scale", scale, envir=env);
>> bar <- function(x) { scale * x };
>> environment(bar) <- env;
>> bar;
>> }
>>
>> fcn <- foo3(1:10e5)
>>
>> But,
>>
>> env <- environment(fcn)
>> save(env, file="temp.RData");
>> file.info("temp.RData")$size
>> # [1] 2007720
>>
>> When I try to set the parent environment of 'env' to emptyenv(), it
>> does not work, e.g.
>>
>> fcn(2)
>> # Error in fcn(2) : attempt to apply non-function
>>
>> but with the new.env(parent=baseenv()) it works fine. The "base"
>> environment has the empty environment as a parent. So, I try to do
>> the same myself, i.e. new.env(parent=new.env(parent=emptyenv())), but
>> once again I get
>>
>> fcn(2)
>> # Error in fcn(2) : attempt to apply non-function
>>
>> Apparently, I do not understand enough here. Please, enlighten me. In
>> the meantime I stick with foo2().
>>
>> Best,
>>
>> Henrik
>>
>> ______________________________________________
>> R-devel at r-project.org mailing list
>> https://stat.ethz.ch/mailman/listinfo/r-devel
>>
Roger> --
Roger> Roger D. Peng | http://www.biostat.jhsph.edu/~rpeng/
Roger> ______________________________________________
Roger> R-devel at r-project.org mailing list
Roger> https://stat.ethz.ch/mailman/listinfo/r-devel
More information about the R-devel
mailing list