Saving the state of the random number generator
Problem
You want to save and restore the state of the random number generator
Solution
Save .Random.seed
to another variable and then later restore that value to .Random.seed
.
# For this example, set the random seed
set.seed(423)
runif(3)
#> [1] 0.1089715 0.5973455 0.9726307
# Save the seed
oldseed <- .Random.seed
runif(3)
#> [1] 0.7973768 0.2278427 0.5189830
# Do some other stuff with RNG here, such as:
# runif(30)
# ...
# Restore the seed
.Random.seed <- oldseed
# Get the same random numbers as before, after saving the seed
runif(3)
#> [1] 0.7973768 0.2278427 0.5189830
If no random number generator has been used in your R session, the variable .Random.seed
will not exist. If you cannot be certain that an RNG has been used before attempting to save, the seed, you should check for it before saving and restoring:
oldseed <- NULL
if (exists(".Random.seed"))
oldseed <- .Random.seed
# Do some other stuff with RNG here, such as:
# runif(30)
# ...
if (!is.null(oldseed))
.Random.seed <- oldseed
Saving and restoring the state of the RNG in functions
If you attempt to restore the state of the random number generator within a function by using .Random.seed <- x
, it will not work, because this operation changes a local variable named .Random.seed
, instead of the variable in the global envrionment.
Here are two examples. What these functions are supposed to do is generate some random numbers, while leaving the state of the RNG unchanged.
# This is the bad version
bad_rand_restore <- function() {
if (exists(".Random.seed"))
oldseed <- .Random.seed
else
oldseed <- NULL
print(runif(3))
if (!is.null(oldseed))
.Random.seed <- oldseed
else
rm(".Random.seed")
}
# This is the good version
rand_restore <- function() {
if (exists(".Random.seed", .GlobalEnv))
oldseed <- .GlobalEnv$.Random.seed
else
oldseed <- NULL
print(runif(3))
if (!is.null(oldseed))
.GlobalEnv$.Random.seed <- oldseed
else
rm(".Random.seed", envir = .GlobalEnv)
}
# The bad version doesn't properly reset the RNG state, so random numbers keep
# changing.
set.seed(423)
bad_rand_restore()
#> [1] 0.1089715 0.5973455 0.9726307
bad_rand_restore()
#> [1] 0.7973768 0.2278427 0.5189830
bad_rand_restore()
#> [1] 0.6929255 0.8104453 0.1019465
# The good version correctly resets the RNG state each time, so random numbers
# stay the same.
set.seed(423)
rand_restore()
#> [1] 0.1089715 0.5973455 0.9726307
rand_restore()
#> [1] 0.1089715 0.5973455 0.9726307
rand_restore()
#> [1] 0.1089715 0.5973455 0.9726307
Notes
.Random.seed
should not be modified by the user.