rnorm - set seed stata
Arreglando set.seed para una sesiĆ³n completa (5)
Creo que esta pregunta sufre de una confusión. En el ejemplo, la semilla se ha establecido para toda la sesión. Sin embargo, esto no significa que producirá el mismo conjunto de números cada vez que use el comando print(sample))
durante una ejecución; eso no se parecería a un proceso aleatorio, ya que sería completamente determinado que los mismos tres números aparecerían cada vez. En cambio, lo que realmente sucede es que una vez que ha establecido la semilla, cada vez que ejecuta una secuencia de comandos se usa la misma semilla para producir una selección de números pseudoaleatorios, es decir, números que parecen como si fueran aleatorios, pero en realidad producido por un proceso reproducible utilizando la semilla que ha establecido.
Si vuelve a ejecutar el script completo desde el principio, reproducirá los números que parecen aleatorios pero no lo son. Entonces, en el ejemplo, la segunda vez que se establece la semilla en 123, la salida es nuevamente 9, 10 y 1, que es exactamente lo que se esperaría ver porque el proceso se está reiniciando desde el principio. Si continuara reproduciendo su primera ejecución escribiendo print(sample(1:10,3))
, entonces el segundo conjunto de resultados sería nuevamente 3, 8 y 4.
Entonces, la respuesta corta a la pregunta es: si desea establecer una semilla para crear un proceso reproducible, haga lo que ha hecho y establezca la semilla una vez; sin embargo, no debe establecer el valor de inicialización antes de cada sorteo aleatorio porque eso iniciará el proceso pseudoaleatorio nuevamente desde el principio.
Esta pregunta es antigua, pero sigue siendo alta en los resultados de búsqueda, y parece que vale la pena ampliar la respuesta de Spacedman.
Estoy usando R para construir un modelo basado en agente con un proceso de Monte Carlo. Esto significa que tengo muchas funciones que usan un motor aleatorio de algún tipo. Para obtener resultados reproducibles, debo arreglar la semilla. Pero, por lo que entiendo, debo establecer la semilla antes de cada sorteo o muestra aleatoria. Este es un verdadero dolor en el cuello. ¿Hay alguna manera de arreglar la semilla?
set.seed(123)
print(sample(1:10,3))
# [1] 3 8 4
print(sample(1:10,3))
# [1] 9 10 1
set.seed(123)
print(sample(1:10,3))
# [1] 3 8 4
Hay varias opciones, dependiendo de sus necesidades exactas. Sospecho que la primera opción, la más simple no es suficiente, pero mi segunda y tercera opción pueden ser más apropiadas, con la tercera opción la más automatizable.
Opción 1
Si sabe de antemano que la función que utiliza / crea números aleatorios siempre dibujará el mismo número y no reordena las llamadas de función ni inserta una nueva llamada entre las existentes, entonces todo lo que necesita hacer es establecer la semilla una vez. De hecho, es probable que no desee seguir reiniciando la semilla, ya que seguirá obteniendo el mismo conjunto de números aleatorios para cada llamada de función.
Por ejemplo:
> set.seed(1)
> sample(10)
[1] 3 4 5 7 2 8 9 6 10 1
> sample(10)
[1] 3 2 6 10 5 7 8 4 1 9
>
> ## second time round
> set.seed(1)
> sample(10)
[1] 3 4 5 7 2 8 9 6 10 1
> sample(10)
[1] 3 2 6 10 5 7 8 4 1 9
opcion 2
Si realmente quieres asegurarte de que una función usa la misma semilla y solo quieres establecerla una vez, pasa la semilla como un argumento:
foo <- function(...., seed) {
## set the seed
if (!missing(seed))
set.seed(seed)
## do other stuff
....
}
my.seed <- 42
bar <- foo(...., seed = my.seed)
fbar <- foo(...., seed = my.seed)
(donde ....
significa otros argumentos para su función; esto es un pseudo código).
Opcion 3
Si desea automatizar esto aún más, entonces podría abusar del mecanismo de options
, lo cual está bien si solo está haciendo esto en un script (para un paquete, debe usar su propio objeto de opciones). Entonces su función puede buscar esta opción. P.ej
foo <- function() {
if (!is.null(seed <- getOption("myseed")))
set.seed(seed)
sample(10)
}
Entonces en uso tenemos:
> getOption("myseed")
NULL
> foo()
[1] 1 2 9 4 8 7 10 6 3 5
> foo()
[1] 6 2 3 5 7 8 1 4 10 9
> options(myseed = 42)
> foo()
[1] 10 9 3 6 4 8 5 1 2 7
> foo()
[1] 10 9 3 6 4 8 5 1 2 7
> foo()
[1] 10 9 3 6 4 8 5 1 2 7
> foo()
[1] 10 9 3 6 4 8 5 1 2 7
Le sugiero que set.seed
antes de llamar a cada generador de números aleatorios en R. Creo que lo que necesita es reproducibilidad para las simulaciones de Monte Carlo. Si está en un bucle for
, puede establecer. set.seed(i)
antes de llamar a sample
, lo que garantiza que sea completamente reproducible. En su función externa, puede especificar un argumento seed=1
modo que en el bucle for
, use set.seed(i+seed)
.
No hay necesidad. Aunque los resultados son diferentes de una muestra a otra (lo que es casi seguro que usted desea, de lo contrario la aleatoriedad es muy cuestionable), los resultados de una ejecución a otra serán los mismos. Mira, aquí está la salida de mi máquina.
> set.seed(123)
> sample(1:10,3)
[1] 3 8 4
> sample(1:10,3)
[1] 9 10 1
Podrías hacer una función de envoltura, así:
> wrap.3.digit.sample <- function(x) {
+ set.seed(123)
+ return(sample(x, 3))
+ }
> wrap.3.digit.sample(c(1:10))
[1] 3 8 4
> wrap.3.digit.sample(c(1:10))
[1] 3 8 4
Probablemente haya una forma más elegante, y estoy seguro de que alguien la apoyará. Pero, si no lo hacen, esto debería hacer su vida más fácil.