【问题标题】:setting seed locally (not globally) in R在 R 中本地(不是全局)设置种子
【发布时间】:2012-12-28 17:54:57
【问题描述】:

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

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

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

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

【问题讨论】:

    标签: r global local seeding


    【解决方案1】:

    这样的事情对我有用:

    myfunction <- function () {
      old <- .Random.seed
      set.seed(2)
      res <- runif(1)
      .Random.seed <<- old
      res
    }
    

    或者更优雅:

    myfunction <- function () {
      old <- .Random.seed
      on.exit( { .Random.seed <<- old } )
      set.seed(2)
      runif(1)
    }
    

    例如:

    > myfunction()
    [1] 0.1848823
    > runif(1)
    [1] 0.3472722
    > myfunction()
    [1] 0.1848823
    > runif(1)
    [1] 0.4887732
    

    【讨论】:

    • +1 打败我。 @ManoelGaldino 至于“为什么?”我不认为这是出乎意料的。我认为,为每个函数环境实现一个新的、单独的随机生成器将非常复杂。并且可能会带来一些性能开销。
    • 我确实认为有人比我更了解这个问题如何影响并行进程。
    • 这个答案有一个小问题。如果尚未设置种子或 runif()(或访问随机数生成器的其他函数)尚未在当前 R 会话中调用,则对象 .Random.seed 可能不存在。因此,在存储.Random.seed 之前,需要使用exists() 检查它的存在,如果不存在则可能调用runif()。
    • @TheodoreLytras 在理想情况下,set.seed 将返回种子的旧值。
    • 这是一个很好的答案。一个问题,&lt;&lt;-- 不会总是推送到父框架吗?我们不应该使用assignenvir = globalenv 来确保old 被推回全局环境吗?
    【解决方案2】:

    使用@Romain Francois 的答案,概括为函数:

    withRandom <- function(expr, seed = 1) {
        old <- .Random.seed
        on.exit({.Random.seed <<- old})
        set.seed(seed)
        expr
    }
    

    用法:

    runif(2)
    withRandom(seed = 2, {
        runif(1)
        runif(1)
    })
    runif(2)
    withRandom(seed = 2, runif(2))
    runif(2)
    

    输出:

    > runif(2)
    [1] 0.5776099 0.6309793
    > withRandom(seed = 2, {
    +     runif(1)
    +     runif(1)
    + })
    [1] 0.702374
    > runif(2)
    [1] 0.5120159 0.5050239
    > withRandom(seed = 2, runif(2))
    [1] 0.1848823 0.7023740
    > runif(2)
    [1] 0.5340354 0.5572494
    
    

    【讨论】:

      猜你喜欢
      • 2017-06-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-25
      • 2014-10-05
      • 1970-01-01
      • 1970-01-01
      • 2017-06-16
      相关资源
      最近更新 更多