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

2022-09-19 Thread Jan van der Laan

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@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-package-devel




__
R-package-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-package-devel


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

2022-09-19 Thread Jan van der Laan



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]]


Thanks.
Jan

[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@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-package-devel