R ignores setting .Random.seed
inside of an lapply. Using set.seed
however, works fine.
Some code:
# 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
My goal is to checkpoint MCMC runs so that they can be resumed exactly. I can easily save the state of the RNG, I just can't get R to load it inside of an lapply loop!
Is there a way to force R to notice setting .Random.seed
? Or is there a simpler way to make this happen?
In case it matters, I'm using 64 bit R:
R version 2.15.1 (2012-06-22) -- "Roasted Marshmallows"
Platform: x86_64-pc-linux-gnu (64-bit)
On 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
This happens because .Random.seed
is evaluated as a local object inside your call to lapply
.
You need to assign the value of .Random.seed
in the global environment:
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
The reason your code doesn't work is that .Random.seed
get assigned in the environment of the anonymous function in lapply
, but rnorm()
looks for .Random.seed
in the global environment.
For the record, here is my first attempt, which will only work in some situations:
Here is one way to fix it, by using <<-
. (Yes, I know this is frowned upon, but possibly justified. An alternative would be to use eval()
and force evaluation in a calling environment.
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
Note that this solution will not work if your lapply()
is nested in another function, since <<-
only evaluates in the parent environment, not the global environment.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With