在R中本地(非全局)设置种子

Man*_*ino 26 global r local seeding

我想在R中仅在本地设置种子(内部函数),但似乎R不仅在本地设置种子,而且在全局设置种子.这是我正在尝试(不)做的一个简单示例.

myfunction <- function () {
  set.seed(2)
}

# now, whenever I run the two commands below I'll get the same answer
myfunction()
runif(1)
Run Code Online (Sandbox Code Playgroud)

所以,我的问题是:为什么R在全局设置种子,而不仅仅是在我的函数中?以及如何让R只在我的函数中设置种子?

Rom*_*ois 36

像这样的东西对我来说:

myfunction <- function () {
  old <- .Random.seed
  set.seed(2)
  res <- runif(1)
  .Random.seed <<- old
  res
}
Run Code Online (Sandbox Code Playgroud)

或者更优雅:

myfunction <- function () {
  old <- .Random.seed
  on.exit( { .Random.seed <<- old } )
  set.seed(2)
  runif(1)
}
Run Code Online (Sandbox Code Playgroud)

例如:

> myfunction()
[1] 0.1848823
> runif(1)
[1] 0.3472722
> myfunction()
[1] 0.1848823
> runif(1)
[1] 0.4887732
Run Code Online (Sandbox Code Playgroud)

  • 这个答案有一个小问题.如果尚未设置种子,则可能不存在对象`.Random.seed`或者在当前R会话中未调用`runif()`(或访问随机数生成器的其他函数).因此,在存储`.Random.seed`之前,需要使用`exists()`检查它的存在,如果不存在则可能调用runif(). (11认同)
  • 我确实认为比我知识更多的人应评论这个问题如何影响并行进程. (4认同)
  • @TheodoreLytras在理想世界中,`set.seed`将返回种子的旧值. (3认同)
  • 这是一个很好的答案。一个问题,**`&lt;&lt;--`** 不会总是推送到父框架吗?我们不应该使用 `assign` 和 `envir = globalenv` 来确保将 `old` 推回全局环境吗? (2认同)