How can I set a seed while my function runs but leave user's .GlobalEnv unchanged?

My goal is to ensure consistent output of a function that uses randomized computation.

  • The code below achieves my goal but I believe the seed I set overwrites the user's seed.
# The output of kmeans is inconsistent accross runs
replicate(5, stats::kmeans(1:3, centers = 2)$cluster)
#>      [,1] [,2] [,3] [,4] [,5]
#> [1,]    1    1    2    2    1
#> [2,]    1    1    1    1    2
#> [3,]    2    2    1    1    2

# Enforce consistent runs
consistent_kmeans <- function(...) {
  set.seed(1)
  stats::kmeans(...)
}

# Consistent
replicate(5, consistent_kmeans(1:3, centers = 2)$cluster)
#>      [,1] [,2] [,3] [,4] [,5]
#> [1,]    1    1    1    1    1
#> [2,]    1    1    1    1    1
#> [3,]    2    2    2    2    2
  • This restores the user's seed before exiting the function, but I get a complaing note in R CMD check:
consistent_kmeans <- function(...) {
  old_seed <- get(".Random.seed", .GlobalEnv)
  on.exit(assign(".Randon.seed", old_seed, .GlobalEnv))

  set.seed(1)
  stats::kmeans(...)
}

image

Created on 2018-08-09 by the reprex package (v0.2.0.9000

withr::with_seed()

3 Likes

Awesome! That worked!:slight_smile: