[R-pkg-devel] Read and restore .Random.seed in package

Jan van der Laan rhe|p @end|ng |rom eoo@@dd@@n|
Mon Sep 19 13:19:35 CEST 2022


Thanks!

I noticed that there was an almost identical question asked on this list 
only a few days ago that I completely missed. Sorry for that. Your 
example and the examples there at least give me a better way to write my 
function.

Jan


On 19-09-2022 11:58, Achim Zeileis wrote:
> On Mon, 19 Sep 2022, Jan van der Laan wrote:
> 
>>
>> I have a function in which I need to draw some random numbers. 
>> However, for some use cases, it is necessary that the same random 
>> numbers are drawn (when the input is the same) [1]. So I would like to 
>> do a set.seed in my function. This could, however, mess up the seed 
>> set by the user. So what I would like to do is store .Random.seed, 
>> call set.seed, draw my random numbers and restore .Random.seed to its 
>> original value. For an example see the bottom of the mail.
>>
>> Am I allowed on CRAN to read and restore .Random.seed in a package 
>> function? This seems to conflict with the "Packages should not modify 
>> the global environment (user’s workspace)." policy. Is there another 
>> way to get the same random numbers each time a function is called 
>> without messing up the seed set by the user? [2]]
> 
> My understanding is that restoring the .Random.seed is exempt from this 
> policy. See the first lines in stats:::simulate.lm for how R itself 
> deals with this situation:
> 
> simulate.lm <- function(object, nsim = 1, seed = NULL, ...)
> {
>      if(!exists(".Random.seed", envir = .GlobalEnv, inherits = FALSE))
>          runif(1)                     # initialize the RNG if necessary
>      if(is.null(seed))
>          RNGstate <- get(".Random.seed", envir = .GlobalEnv)
>      else {
>          R.seed <- get(".Random.seed", envir = .GlobalEnv)
>      set.seed(seed)
>          RNGstate <- structure(seed, kind = as.list(RNGkind()))
>          on.exit(assign(".Random.seed", R.seed, envir = .GlobalEnv))
>      }
> 
> [...]
> 
>>
>> [1] Records are randomly distributed over cluster nodes. For some use 
>> cases it is necessary that the same records end up on the same cluster 
>> nodes when the function is called multiple times.
>>
>> [2] A possible solution would be to document that the user should 
>> ensure that the same seed is used when calling this function for the 
>> use cases where this is needed.
>>
>>
>> set_seed <- function(seed, ...) {
>>  if (!exists(".Random.seed")) set.seed(NULL)
>>  old_seed <- .Random.seed
>>  if (length(seed) > 1) {
>>    .Random.seed <<- seed
>>  } else {
>>    set.seed(seed, ...)
>>  }
>>  invisible(old_seed)
>> }
>>
>> foo <- function(n) {
>>  old_seed <- set_seed(1)
>>  on.exit(set_seed(old_seed))
>>  runif(n)
>> }
>>
>> Using these:
>>
>>> set.seed(2)
>>> foo(5)
>> [1] 0.2655087 0.3721239 0.5728534 0.9082078 0.2016819
>>> runif(5)
>> [1] 0.1848823 0.7023740 0.5733263 0.1680519 0.9438393
>>> foo(5)
>> [1] 0.2655087 0.3721239 0.5728534 0.9082078 0.2016819
>>> runif(5)
>> [1] 0.9434750 0.1291590 0.8334488 0.4680185 0.5499837
>>
>> ______________________________________________
>> R-package-devel using r-project.org mailing list
>> https://stat.ethz.ch/mailman/listinfo/r-package-devel
>>
>>



More information about the R-package-devel mailing list