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