【问题标题】:How can I get R's lapply (and mclapply) to restore the state of the random number generator?如何让 R 的 lapply(和 mclapply)恢复随机数生成器的状态?
【发布时间】:2012-07-07 20:05:55
【问题描述】:

R 忽略在 lapply 内设置 .Random.seed。但是,使用 set.seed 可以正常工作。

一些代码:

# I can save the state of the RNG for a few seeds
seed.list <- lapply( 1:5, function(x) {
                        set.seed(x)
                        seed.state <- .Random.seed
                        print( rnorm(1) )
                        return( seed.state )}) 
#[1] -0.6264538
#[1] -0.8969145
#[1] -0.9619334

# But I get different numbers if I try to restore 
# the state of the RNG inside of an lapply
tmp.rest.state <-  lapply(1:5, function(x) { 
                        .Random.seed <- seed.list[[x]]
                        print(rnorm(1))})
# [1] -0.2925257
# [1] 0.2587882
# [1] -1.152132

# lapply is just ignoring the assignment of .Random.seed
.Random.seed <- seed.list[[3]]
print( rnorm(1) ) # The last printed value from seed.list
# [1] -0.9619334
print( rnorm(1) ) # The first value in tmp.rest.state
# [1] -0.2925257

我的目标是检查点 MCMC 运行,以便它们可以准确地恢复。我可以轻松保存 RNG 的状态,只是无法让 R 在 lapply 循环中加载它!

有没有办法强制 R 注意到设置.Random.seed?或者有没有更简单的方法来实现这一点?

以防万一,我使用的是 64 位 R:

R version 2.15.1 (2012-06-22) -- "Roasted Marshmallows"
Platform: x86_64-pc-linux-gnu (64-bit)

在 Ubuntu 12.04 LTS 上:

nathanvan@nathanvan-N61Jq:~$ uname -a
Linux nathanvan-N61Jq 3.2.0-26-generic #41-Ubuntu SMP Thu Jun 14 17:49:24 UTC 2012 x86_64 x86_64 x86_64 GNU/Linux

【问题讨论】:

  • +1 非常有趣的问题,谢谢。

标签: r random lapply mclapply


【解决方案1】:

发生这种情况是因为 .Random.seed 在您对 lapply 的调用中被评估为本地对象。

需要在全局环境中赋值.Random.seed

tmp.rest.state <- lapply(seed.list, function(x) {
    assign(".Random.seed", x, envir=globalenv())
    print(rnorm(1))
  }
)

[1] -0.6264538
[1] -0.8969145
[1] -0.9619334
[1] 0.2167549
[1] -0.8408555

您的代码不起作用的原因是.Random.seedlapply 的匿名函数环境中被分配,但rnorm() 在全局环境中查找.Random.seed


作为记录,这是我的第一次尝试,仅在某些情况下有效:

这是修复它的一种方法,使用&lt;&lt;-。 (是的,我知道这是不受欢迎的,但可能是合理的。另一种方法是使用 eval() 并在调用环境中强制评估。

tmp.rest.state <- lapply(seed.list, function(x) {
    .Random.seed <<- x
    print(rnorm(1))
  }
)

[1] -0.6264538
[1] -0.8969145
[1] -0.9619334
[1] 0.2167549
[1] -0.8408555

请注意,如果您的 lapply() 嵌套在另一个函数中,则此解决方案将不起作用,因为 &lt;&lt;- 仅在父环境中计算,而不是在全局环境中计算。

【讨论】:

  • 也许将 .Random.seed 粘贴在命名环境中会增加通用性?还是参考类解决方案?
  • 也可以使用.GlobalEnv$.Random.seed &lt;- x.GlobalEnv[[".Random.seed"]] &lt;- x
  • "请注意,如果您的 lapply() 嵌套在另一个函数中,则此解决方案将不起作用,因为 <<- 将首先在父环境中查找是否存在具有正确名称的对象,然后转到祖父环境,依此类推。如果没有找到变量,则在全局环境中进行赋值。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-08-25
  • 1970-01-01
  • 2020-02-03
  • 2013-10-30
  • 2019-08-22
  • 2019-08-01
  • 1970-01-01
相关资源
最近更新 更多