问题 如何让R的lapply(和mclapply)恢复随机数生成器的状态?


R忽略设置 .Random.seed 在一个lapply里面。运用 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

10025
2017-07-07 19:08


起源

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


答案:


这是因为 .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.seed 在匿名函数的环境中分配 lapply但是 rnorm() 寻找 .Random.seed 在全球环境中。


为了记录,这是我的第一次尝试,它只适用于某些情况:

这是通过使用来解决它的一种方法 <<-。 (是的,我知道这是不赞成的,但可能是合理的。另一种方法是使用 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() 嵌套在另一个函数中,因为 <<- 仅在父环境中进行评估,而不是在全局环境中进行评估。


10
2017-07-07 19:24



也许坚持.Random.seed在命名环境中会增加一般性?还是参考类解决方案? - 42-
也可以使用 .GlobalEnv$.Random.seed <- x 要么 .GlobalEnv[[".Random.seed"]] <- x。 - Josh O'Brien
这很棒,谢谢! - Nathan VanHoudnos