例えば、関数Aはユーザーが乱数を固定して何かしたいものだとして、関数Bは乱数を固定せず何かしたいものだとする。
A <- function(seeds=123){
set.seed(seeds)
}
B <- function(){
print(runif(1))
print(runif(1))
print(runif(1))
}
もし関数Bを実行する前に、関数Aを実行してしまった場合、例えそれが関数の中で評価されたものだとしても、乱数が固定された状態が続いてしまうらしい。
A()
B()
# > A()
# > B()
# [1] 0.2875775
# [1] 0.7883051
# [1] 0.4089769
A()
B()
# > A()
# > B()
# [1] 0.2875775
# [1] 0.7883051
# [1] 0.4089769
関数Aがテストデータ生成、関数Bが乱数を元にしたアルゴリズムだったりした場合、乱数が固定されて毎回同じ結果を返しているだけなのに、やけに収束が良いアルゴリズムだと勘違いしてしまいそうだ。
なので、set.seed(数字)のあとは、以下のように必ずどこかでset.seed(NULL)を入れないと、予期せぬことが起こりそう。
A <- function(seeds=123){
set.seed(seeds)
set.seed(NULL)
}
B <- function(){
print(runif(1))
print(runif(1))
print(runif(1))
}
A()
B()
# > A()
# > B()
# [1] 0.7819413
# [1] 0.4793704
# [1] 0.8743641
A()
B()
# > A()
# > B()
# [1] 0.7548444
# [1] 0.07935513
# [1] 0.7085605
A()
B()
# > A()
# > B()
# [1] 0.2875775
# [1] 0.7883051
# [1] 0.4089769
A()
set.seed(NULL)
B()
# > A()
# > set.seed(NULL)
# > B()
# [1] 0.5758005
# [1] 0.4120173
# [1] 0.2110562