19

I'm an R newbie here.

let say I have the line of code

set.seed(123456)

then I want to get the value 123456 so I can print it out for documentation purposes, and if need be reenter the value sometime in the future. So how do I get that seed?

Note that I may comment the above line of code out, so I won't actually know what that the seed is at 123456. Therefore I need r to print out the location of the current seed as a single integer, not as a list of 626 integers.

Ben Bolker
  • 211,554
  • 25
  • 370
  • 453
Joe_Schmoe
  • 1,485
  • 3
  • 17
  • 19

3 Answers3

25

There's effectively a one-way relationship between the seed used in set.seed() and the information in .Random.seed; as ?Random.seed says and @MattTenenbaum's answer shows, the information in .Random.seed can be saved and restored. I appreciate the desire for a function that would derive a simple integer seed from the current state of .Random.seed, but in its absence, you have to save and restore the full information ... for example

set.seed(1001)
save(".Random.seed",file="random_state_seed1001.RData") ## save current state
runif(1)
## [1] 0.9856888
runif(1)
## [1] 0.4126285
runif(1)
## [1] 0.4295392
load("random_state_seed1001.RData") ## restore state just after set.seed()
runif(1)
## [1] 0.9856888

As @JoshuaUlrich points out, this only works/is only safe if you don't modify the type of RNG (and type of normal deviate generator) between saving and restoring ...

A more complete solution:

save_rng <- function(savefile=tempfile()) {
    if (exists(".Random.seed"))  {
        oldseed <- get(".Random.seed", .GlobalEnv)
    } else stop("don't know how to save before set.seed() or r*** call")
    oldRNGkind <- RNGkind()
    save("oldseed","oldRNGkind",file=savefile)
    invisible(savefile)
}

restore_rng <- function(savefile) {
    load(savefile)
    do.call("RNGkind",as.list(oldRNGkind))  ## must be first!
    assign(".Random.seed", oldseed, .GlobalEnv)
}

Try it out:

set.seed(101)
RNGstore <- save_rng()  ## save file name
runif(1)
## [1] 0.3721984
runif(10)
## [1] 0.04382482 0.70968402 0.65769040 0.24985572 0.30005483 0.58486663
## [7] 0.33346714 0.62201196 0.54582855 0.87979573
restore_rng(RNGstore)
runif(1)
## [1] 0.3721984

See also: http://www.cookbook-r.com/Numbers/Saving_the_state_of_the_random_number_generator/

Ben Bolker
  • 211,554
  • 25
  • 370
  • 453
  • 1
    This isn't really a safe solution without also ensuring the RNG kind and normal kind are currently set to the values implied by `.Random.seed`. – Joshua Ulrich Dec 21 '12 at 21:56
  • @JoshuaUlrich, do you know if there's a worked example lying around out there somewhere of saving and restoring the complete RNG state (it's not in `example(".Random.seed")` as far as I can tell)? If not I might go to the trouble of editing my question, otherwise I'll just link to it ... – Ben Bolker Dec 21 '12 at 22:04
  • I don't know of any such example; I doubt there is one because that's what `set.seed` is for. – Joshua Ulrich Dec 21 '12 at 22:19
  • 1
    @JoshuaUlrich: I agree `set.seed` is usually the right way to go, but I can think of cases (e.g. checkpointing in the middle of a big simulation run) where one *might* prefer this approach ... – Ben Bolker Dec 21 '12 at 22:50
3

Once you have called set.seed, you should be able to reference .Random.seed (see http://stat.ethz.ch/R-manual/R-patched/library/base/html/Random.html for further info).

A simple example:

set.seed(123)
tmp <- .Random.seed
> runif(10)
 [1] 0.2875775 0.7883051 0.4089769 0.8830174 0.9404673 0.0455565 0.5281055 0.8924190 0.5514350 0.4566147
.Random.seed <- tmp
> runif(10)
 [1] 0.2875775 0.7883051 0.4089769 0.8830174 0.9404673 0.0455565 0.5281055 0.8924190 0.5514350 0.4566147
joran
  • 169,992
  • 32
  • 429
  • 468
Matt Tenenbaum
  • 1,321
  • 10
  • 11
3

Here's something that should work just fine in practice (but shouldn't be used for e.g. cryptography):

new.seed <- as.integer(runif(1)*2e9)
cat("Random seed: ", new.seed, "\n")
set.seed(new.seed)

You do need to actually set the seed for this to work, so it's not quite an answer to the original question, but might be what you were looking for, as it lets you have an easily specified random seed without setting it manually with a prespecified integer.

petrelharp
  • 4,829
  • 1
  • 16
  • 17