[R] How to test existence of an environment and how to remove it (from within functions)?

Marius Hofert marius.hofert at uwaterloo.ca
Mon Aug 29 19:36:17 CEST 2016


Hi,

I have a function main() which calls another function aux() many times. aux()
mostly does the same operations based on an object and thus I would like it to
compute and store this object for each call from main() only once.

Below are two versions of a MWE. The first one computes the right result (but is
merely there for showing what I would like to have; well, apart from the
environment .my_environ still floating around after main() is called).
It works with an
environment .my_environ in which the computed object is stored. The
second MWE tries to set
up the environment inside aux(), but neither the check of existence in
aux() nor the
removal of the whole environment in main() work (see 'TODO' below). How can this
be achieved?

Cheers,
Marius


### Version 1: Setting up the environment in .GlobalEnv ########################

.my_environ <- new.env(hash = FALSE, parent = emptyenv()) # define the
environment

## Auxiliary function with caching
aux <- function(x) {
    ## Setting up the environment and caching
    if(exists("cached.obj", envir = .my_environ)) { # look-up (in case
the object already exists)
        x.cols <- get("cached.obj", .my_environ)
    } else { # time-consuming part (+ cache)
        x.cols <- split(x, col(x))
        Sys.sleep(1)
        assign("cached.obj", x.cols, envir = .my_environ)
    }
    ## Do something with the result from above (here: pick out two randomly
    ## chosen columns)
    x.cols[sample(1:1000, size = 2)]
}

## Main function
main <- function() {
    x <- matrix(rnorm(100*1000), ncol = 1000)
    res <- replicate(5, aux(x))
    rm(cached.obj, envir = .my_environ) # only removing the *object*
(but not the environment)
    res
}

## Testing
set.seed(271)
system.time(main()) # => ~ 1s since the cached object is found


### Version 2: Trying to set up the environment inside aux() ###################

## Auxiliary function with caching
aux <- function(x) {
    ## Setting up the environment and caching
    if(!exists(".my_environ", mode = "environmnent")) # TODO: How to
check the existence of the environment? This is always TRUE...
        .my_environ <- new.env(hash = FALSE, parent = emptyenv()) #
define the environment
    if(exists("cached.obj", envir = .my_environ)) { # look-up (in case
the object already exists)
        x.cols <- get("cached.obj", .my_environ)
    } else { # time-consuming part (+ cache)
        x.cols <- split(x, col(x))
        Sys.sleep(1)
        assign("cached.obj", x.cols, envir = .my_environ)
    }
    ## Do something with the result from above (here: pick out two randomly
    ## chosen columns)
    x.cols[sample(1:1000, size = 2)]
}

## Main function
main <- function() {
    x <- matrix(rnorm(100*1000), ncol = 1000)
    res <- replicate(5, aux(x))
    rm(.my_environ) # TODO: How to properly remove the environment?
    res
}

## Testing
set.seed(271)
system.time(main()) # => ~ 5s since (the cached object in) environment
.my_environ is not found



More information about the R-help mailing list