2012-07-07 7 views
11

R ignora la configuración .Random.seed dentro de una aplicación. Sin embargo, usar set.seed funciona bien.¿Cómo puedo obtener la aplicación de R (y aplicar) para restaurar el estado del generador de números aleatorios?

Algunos código:

# 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 

Mi objetivo es checkpoint MCMC se ejecuta de manera que se pueden reanudar exactamente. Puedo guardar fácilmente el estado del RNG, ¡simplemente no puedo hacer que R lo cargue dentro de un bucle de aplicación!

¿Hay alguna manera de forzar que R note la configuración .Random.seed? ¿O hay una manera más simple de hacer que esto suceda?

En caso de que importa, estoy usando 64 bits R:

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

En Ubuntu 12.04 LTS:

n[email protected]:~$ 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 
+0

+1 Pregunta muy interesante, gracias. – Andrie

Respuesta

10

Esto sucede porque .Random.seed se evalúa como un objeto local dentro de su llamada a lapply.

tiene que asignar el valor de .Random.seed en el entorno global:

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 

La razón por la que su código no funciona es que .Random.seed se asignan en el entorno de la función anónima en lapply, pero rnorm() miradas para .Random.seed en el entorno global.


Para el registro, que aquí es mi primer intento, que sólo funcionará en algunas situaciones:

Aquí es una manera de solucionarlo, mediante el uso de <<-. (Sí, sé que esto está mal visto, pero posiblemente justificada. Una alternativa sería utilizar eval() y evaluación vigente en un entorno de la llamada.

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 

Tenga en cuenta que esta solución no funcionará si su lapply() está anidado en otro función, ya que <<- solo evalúa en el entorno principal, no en el entorno global.

+1

¿Quizás la inclusión de .Random.seed en un entorno con nombre aumentaría la generalidad? O una solución de clase de referencia ? –

+4

También podría usar '.GlobalEnv $ .Random.seed <- x' o' .GlobalEnv [[". Random.seed"]] <- x'. –

+0

¡Esto funciona genial, gracias! –

Cuestiones relacionadas