将来自 @r2evans 和 @Dave2e 的有用 cmets 扩展为答案。
1) .Random.seed[1]
来自?.Random.seed,它说:
".Random.seed 是一个整数向量,其第一个元素编码
一种 RNG 和普通生成器。最低两位小数在
0:(k-1) 其中k 是可用RNG 的数量。数百个
表示正常生成器的类型(从 0 开始),十
千代表离散均匀采样器的类型。”
因此,除非更改生成器方法 (RNGkind),否则第一个值不会更改。
以下是每个可用RNGkinds 的小演示:
library(tidyverse)
# available RNGkind options
kinds <- c(
"Wichmann-Hill",
"Marsaglia-Multicarry",
"Super-Duper",
"Mersenne-Twister",
"Knuth-TAOCP-2002",
"Knuth-TAOCP",
"L'Ecuyer-CMRG"
)
# test over multiple seeds
seeds <- c(1:3)
f <- function(kind, seed) {
# set seed with simulation parameters
set.seed(seed = seed, kind = kind)
# check value of first element in .Random.seed
return(.Random.seed[1])
}
# run on simulated conditions and compare value over different seeds
expand_grid(kind = kinds, seed = seeds) %>%
pmap(f) %>%
unlist() %>%
matrix(
ncol = length(seeds),
byrow = T,
dimnames = list(kinds, paste0("seed_", seeds))
)
#> seed_1 seed_2 seed_3
#> Wichmann-Hill 10400 10400 10400
#> Marsaglia-Multicarry 10401 10401 10401
#> Super-Duper 10402 10402 10402
#> Mersenne-Twister 10403 10403 10403
#> Knuth-TAOCP-2002 10406 10406 10406
#> Knuth-TAOCP 10404 10404 10404
#> L'Ecuyer-CMRG 10407 10407 10407
由reprex package (v2.0.1) 于 2022-01-06 创建
2) .Random.seed[2]
至少对于默认的"Mersenne-Twister" 方法,.Random.seed[2] 是一个指示随机集中当前位置的索引。来自文档:
“种子”是一组 624 维的 32 位整数加上当前
在该集合中的位置。
当使用种子的随机进程被执行时,它会被更新。但是对于其他方法,文档没有提到类似的内容,并且似乎没有明显的趋势。
下面是.Random.seed[2] 在set.seed() 之后迭代随机过程的变化示例。
library(tidyverse)
# available RNGkind options
kinds <- c(
"Wichmann-Hill",
"Marsaglia-Multicarry",
"Super-Duper",
"Mersenne-Twister",
"Knuth-TAOCP-2002",
"Knuth-TAOCP",
"L'Ecuyer-CMRG"
)
# create function to run random process and report .Random.seed[2]
t <- function(n = 1) {
p <- .Random.seed[2]
runif(n)
p
}
# create function to set seed and iterate a random process
f2 <- function(kind, seed = 1, n = 5) {
set.seed(seed = seed,
kind = kind)
replicate(n, t())
}
# set simulation parameters
trials <- 5
seeds <- 1:2
x <- expand_grid(kind = kinds, seed = seeds, n = trials)
# evaluate and report
x %>%
pmap_dfc(f2) %>%
mutate(n = paste0("trial_", 1:trials)) %>%
pivot_longer(-n, names_to = "row") %>%
pivot_wider(names_from = "n") %>%
select(-row) %>%
bind_cols(x[,1:2], .)
#> # A tibble: 14 x 7
#> kind seed trial_1 trial_2 trial_3 trial_4 trial_5
#> <chr> <int> <int> <int> <int> <int> <int>
#> 1 Wichmann-Hill 1 23415 8457 23504 2.37e4 2.28e4
#> 2 Wichmann-Hill 2 21758 27800 1567 2.58e4 2.37e4
#> 3 Marsaglia-Multicarry 1 1280795612 945095059 14912928 1.34e9 2.23e8
#> 4 Marsaglia-Multicarry 2 -897583247 -1953114152 2042794797 1.39e9 3.71e8
#> 5 Super-Duper 1 1280795612 -1162609806 -1499951595 5.51e8 6.35e8
#> 6 Super-Duper 2 -897583247 224551822 -624310 -2.23e8 8.91e8
#> 7 Mersenne-Twister 1 624 1 2 3 4
#> 8 Mersenne-Twister 2 624 1 2 3 4
#> 9 Knuth-TAOCP-2002 1 166645457 504833754 504833754 5.05e8 5.05e8
#> 10 Knuth-TAOCP-2002 2 967462395 252695483 252695483 2.53e8 2.53e8
#> 11 Knuth-TAOCP 1 1050415712 999978161 999978161 1.00e9 1.00e9
#> 12 Knuth-TAOCP 2 204052929 776729829 776729829 7.77e8 7.77e8
#> 13 L'Ecuyer-CMRG 1 1280795612 -169270483 -442010614 4.71e8 1.80e9
#> 14 L'Ecuyer-CMRG 2 -897583247 -1619336578 -714750745 2.10e9 -9.89e8
由reprex package (v2.0.1) 于 2022-01-06 创建
在这里您可以看到,从Mersenne-Twister 方法中,.Random.seed[2] 从最大值624 增加到1 并且增加了随机抽取的大小,并且这set.seed(1) 和 set.seed(2) 是相同的。然而,在其他方法中没有看到相同的趋势。为了说明最后一点,请参见 runif(1) 将 .Random.seed[2] 递增 1 而 runif(2) 将其递增 2:
# create function to run random process and report .Random.seed[2]
t <- function(n = 1) {
p <- .Random.seed[2]
runif(n)
p
}
set.seed(1, kind = "Mersenne-Twister")
replicate(9, t(1))
#> [1] 624 1 2 3 4 5 6 7 8
set.seed(1, kind = "Mersenne-Twister")
replicate(5, t(2))
#> [1] 624 2 4 6 8
由reprex package (v2.0.1) 于 2022-01-06 创建
3) 顺序随机数
因为.Random.seed 的索引或状态(显然对于所有 RNG 方法)根据“随机抽取”的大小(从.Random.seed 生成的随机值的数量)前进,因此可以生成来自同一个种子的同一系列随机数以不同大小的增量。此外,只要在设置相同种子后,在序列中的相同点运行相同的随机过程,似乎就会得到相同的结果。请注意以下示例:
# draw 3 at once
set.seed(1, kind = "Mersenne-Twister")
sample(100, 3, T)
#> [1] 68 39 1
# repeat single draw 3 times
set.seed(1, kind = "Mersenne-Twister")
sample(100, 1)
#> [1] 68
sample(100, 1)
#> [1] 39
sample(100, 1)
#> [1] 1
# draw 1, do something else, draw 1 again
set.seed(1, kind = "Mersenne-Twister")
sample(100, 1)
#> [1] 68
runif(1)
#> [1] 0.5728534
sample(100, 1)
#> [1] 1
由reprex package (v2.0.1) 于 2022-01-06 创建
4) 相关随机数
正如我们在上面看到的,在设置相同种子后,两个随机进程在同一点运行,预计会给出相同的结果。但是,即使您对结果的相似程度提供了限制(例如,通过更改 rnorm() 的 mean 或什至通过提供不同的函数),结果似乎仍然在它们各自的范围内完全相关。
# same function with different constraints
set.seed(1, kind = "Mersenne-Twister")
a <- runif(50, 0, 1)
set.seed(1, kind = "Mersenne-Twister")
b <- runif(50, 10, 100)
plot(a, b)
# different functions
set.seed(1, kind = "Mersenne-Twister")
d <- rnorm(50)
set.seed(1, kind = "Mersenne-Twister")
e <- rlnorm(50)
plot(d, e)
由reprex package 创建于 2022-01-06 (v2.0.1)