問題
你想要保存和恢復(fù)隨機數(shù)生成器的狀態(tài)滑蚯。
方案
將.Random.seed
保存到其他變量,之后將變量值賦給.Random.seed
從而恢復(fù)原來的值鸠踪。
# 這個例子中,先設(shè)定隨機數(shù)種子
set.seed(423)
runif(3)
#> [1] 0.1089715 0.5973455 0.9726307
# 保存種子
oldseed <- .Random.seed
runif(3)
#> [1] 0.7973768 0.2278427 0.5189830
# 做其他隨機數(shù)生成相關(guān)的事情,比如:
# runif(30)
# ...
# 恢復(fù)種子
.Random.seed <- oldseed
# 保存種子之后天梧,像之前那樣得到相同的隨機數(shù)
runif(3)
#> [1] 0.7973768 0.2278427 0.5189830
如果你之前還沒有在R線程中用過隨機數(shù)生成器,變量.Random.seed
將會不存在霞丧。如果你對此不確定呢岗,應(yīng)當(dāng)在保存和恢復(fù)之前進行檢查:
oldseed <- NULL
if (exists(".Random.seed"))
oldseed <- .Random.seed
# 做一些隨機數(shù)生成操作,比如:
# runif(30)
# ...
if (!is.null(oldseed))
.Random.seed <- oldseed
在函數(shù)中保存和恢復(fù)隨機數(shù)生成器的狀態(tài)
如果你試圖在函數(shù)中通過使用 .Random.seed <- x
來恢復(fù)隨機數(shù)生成器的狀態(tài)蛹尝,結(jié)果是行不通的后豫,因為這個操作改變的是名為.Random.seed
的本地變量,而不是全局環(huán)境中的這個變量突那。
這里有兩個例子挫酿。這些函數(shù)想要做的是生成一些隨機數(shù),并使得隨機數(shù)生成器保留未改變的狀態(tài)愕难。
# 這是個壞的版本
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")
}
# 這是個好的版本
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)
}
# 壞的版本沒有合適地重置隨機數(shù)生成器狀態(tài)早龟,因此隨機數(shù)一直在改變
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
# 好的版本每次都正確地重置了隨機數(shù)生成器的狀態(tài)惫霸,因此隨機數(shù)可以保持一致
# 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
注意
使用者最好不要修改.Random.seed
變量。