Как я могу получить R's lapply (и mclapply), чтобы восстановить состояние генератора случайных чисел?
R игнорирует настройку .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, чтобы они могли быть возобновлены точно. Я могу легко сохранить состояние ГСЧ, просто я не могу заставить R загрузить его внутри цикла "Лаппи"!
Есть ли способ заставить 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 ответ
Это происходит потому, что .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()
вложен в другую функцию, так как <<-
оценивает только в родительской среде, а не в глобальной.