[R-pkg-devel] Save and restoring random number seed in a package function

James Pustejovsky jepu@to @end|ng |rom gm@||@com
Wed Sep 14 16:39:23 CEST 2022


I'm interested in this question too. Noah, is there a reason you are using
assign(".Random.seed",...) rather than set.seed()?

On Wed, Sep 14, 2022 at 9:31 AM Noah Greifer <noah.greifer using gmail.com> wrote:

> Hello fellow developers,
>
> I am attempting to solve the problem of saving the state of the random
> generator so that the state can be recovered in a future call. Essentially,
> my function generates random numbers, performs an operation on them (saving
> the result), and throws them out (saving them would require too much
> memory). A second function is meant to take the output of the first
> function, generate the same random numbers, and perform a different
> operation on them.
>
> This is exactly what happens in the *boot* package: the boot() function
> saves the random seed (extracted from .Random.Seed), and the boot.array()
> function extracts the saved seed from the boot() output, sets the seed to
> that value, re-generates the same set of random numbers, and then
> re-sets the seed to what it was before boot.array() was called. This has
> the following benefits: 1) it allows the same random numbers to be drawn;
> 2) the random numbers don't need to be saved, which is good because they
> would take up a lot of memory and boot.array() is an optional function (it
> is used in boot.ci() with type = "bca" for those curious); and 3) the seed
> carries on from where it left off before boot.array() was called instead of
> being set to what it was after boot() was called.
>
> This is implemented in boot in the following way (code abbreviated):
>
> boot <- function(...) {
>   seed <- .Random.Seed
>   #Random numbers generated
>   out <- list(seed = seed
>                   #Other stuff is in this list
>               )
>   out
> }
>
> boot.array <- function(boot.out) {
>   #Save current random seed in `temp`
>   if (exists(".Random.seed", envir = .GlobalEnv, inherits = FALSE))
>     temp <- get(".Random.seed", envir = .GlobalEnv, inherits = FALSE)
>   else temp <- NULL
>
>   #Assign saved seed from boot.out
>   assign(".Random.seed", boot.out$seed, envir = .GlobalEnv)
>
>   #Generate same random numbers from boot() call
>
>   #Restore random seed to what it was before boot.array() call
>   if (!is.null(temp))
>     assign(".Random.seed", temp, envir = .GlobalEnv)
>   else rm(.Random.seed, pos = 1)
> }
>
> This seems to work as intended. However, this violates the CRAN policy of
> changing the global environment. When I used this exact code in a package I
> submitted, the package was rejected for it. The message I received was
>
> > Please do not modify the .GlobalEnv (e.g.: by changing the .Random.seed
> > which is part of the global environment). This is not allowed by the CRAN
> > policies.
>
>
> I'm curious what you think the best course of action might be, and what the
> current policy means for the *boot* package. Thanks for your help.
>
> Noah
>
>         [[alternative HTML version deleted]]
>
> ______________________________________________
> R-package-devel using r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-package-devel
>

	[[alternative HTML version deleted]]



More information about the R-package-devel mailing list