请问R语言怎么设置全局随机数种子?
同一个脚本要产生很多组随机数,怎么保证所有的随机数来自同一组种子?
set.seed只能保证产生的第一组随机数可复现,但再产生第二组时随机数就不同了
R语言设置全局随机数种子
不会吧, 可以验证一下, 只要把随机种子设置了以后,后面产生的随机数应该是一样的,比如
rm(list = ls())
set.seed(10)
x = rnorm(10)
y = runif(10,1,4)
x1 = rnorm(10)
- 已编辑
写个函数放进去,这样你只需要在参数里定义一次即可。不过函数内部仍然是每组随机数前面都要设置随机数种子。
gen_random = function(s = 1024) {
set.seed(s)
x = rnorm(10)
set.seed(s)
y = runif(10, 1, 4)
list(x = x, y = y)
}
zaq
这样肯定是不行的喔,种子数只能保证一次随机数复现。比如这里的X和X1是不一样的。
rm(list = ls())
set.seed(10)
x = rnorm(10)
y = runif(10,1,4)
x1 = rnorm(10)
x
[1] 0.01874617 -0.18425254 -1.37133055 -0.59916772 0.29454513 0.38979430
[7] -1.20807618 -0.36367602 -1.62667268 -0.25647839
x1
[1] 0.08934727 -0.95494386 -0.19515038 0.92552126 0.48297852 -0.59631064
[7] -2.18528684 -0.67486594 -2.11906119 -1.26519802
谢谢呀我试过这样,但是有没有办法减少写set.seed()这个语句的次数呢。就比如说我只写一次set.seed()就可以保证所有的随机数都来自同一组种子
xiaohangzi 我又没说 x1 和 x 一样,我只想说,你运行多次,这产生的随机数都是一样的
- 已编辑
我记得随机种子一旦设定了, 后面的随机数都是固定的,因为计算机中的随机数都是伪随机数。eg:
rm(list = ls())
set.seed(10)
x = rnorm(10)
y = runif(10,1,4)
x1 = rnorm(10)
gen_random = function() {
x = rnorm(10)
y = runif(10, 1, 4)
list(x = x, y = y)
}
(k1 = gen_random())
(k2 = gen_random())
只要你运行上述代码,得到的结果必定如下(下面的 变量名都是独立的,没有任何关系):
> (x = rnorm(10))
[1] 0.01874617 -0.18425254 -1.37133055 -0.59916772 0.29454513 0.38979430 -1.20807618 -0.36367602
[9] -1.62667268 -0.25647839
> (y = runif(10,1,4))
[1] 3.594164 2.846057 3.325330 2.066706 2.217550 3.119941 3.514863 1.718767 3.312315 2.067693
> (x1 = rnorm(10))
[1] 0.08934727 -0.95494386 -0.19515038 0.92552126 0.48297852 -0.59631064 -2.18528684 -0.67486594
[9] -2.11906119 -1.26519802
> (k1 = gen_random())
$x
[1] -0.37366156 -0.68755543 -0.87215883 -0.10176101 -0.25378053 -1.85374045 -0.07794607 0.96856634
[9] 0.18492596 -1.37994358
$y
[1] 1.226711 2.603280 2.924070 2.577218 1.117844 2.637580 2.118289 3.883907 1.772025 1.623855
> (k2 = gen_random())
$x
[1] 1.08655140 -0.76254488 -0.82866254 0.83447390 -0.96765199 -0.02881534 0.23252515 -0.30120868
[9] -0.67761458 0.65522764
$y
[1] 2.033031 1.183968 2.106939 2.222781 3.743010 3.666116 3.951197 2.431586 3.080525 2.277239
zaq
好的呢,我理解啦。我好像没有表述清楚,就是有没有办法保证X和X1是一样的呢。
除了在每组随机数前面都设置随机数种子。
楼主没有描述清楚想要的到底是什么“一致性”导致大家的理解有歧义。对于R
而言,随机数产生的时候都是根据种子得到的伪随机数,所以只要一开始的种子确定,后续代码中产生随机数的代码固定,那么整个流程中的随机数就是可重复的。
楼主的实际需求,是想在每次需要用到某一个随机数的生成的时候都能固定住,那么最直接(甚至本质上也就是唯一的做法)就是每次生成前都设定好种子。
接下来开始偷懒:
如果不想敲这么多次set.seed
,那么实际上可以做一个封装,在函数里包含set.seed
和实际的生成数据的代码,这样可以减少你写set.seed
的次数。另外如果是重复进行生成的话那么考虑并行计算的方式,可以用clusterEvalQ
函数确保每个并行线程的起始种子是一致的;又或者你的并行本身是采用fork机制的那么天然的起始种子就是一致的。
不过话说回来我还是感觉楼主的需求没有描述清楚,你所谓的希望每次的种子都一致具体来说到底是想实现什么呢?如果是要跑20个个rnorm(100)
,还希望每次种子都一致,那干脆直接生成一次,然后复制个20遍就行了?
fenguoerbian
谢谢楼主的耐心解答,确实是我没有表述清楚需求,我下次注意。我想生成的随机变量来自不同的分布,例如epsilon<-rnorm(n,0,1),X1<-runif(n,0,1),X23<-mvrnorm(n,rep(0,2),matrix(c(1,0.5,0.5,1),2,2)),我想保证的是epsilon,X1,X23这几个变量的结果可复现。目前我的做法是在每一次生成随机数时都加上set.seed,但我想的是如果想生成的随机变量很多个,如何减少写set.seed次数。
`> seednum<-666
set.seed(seednum);epsilon<-rnorm(n,0,1)
set.seed(seednum);X1<-runif(n,0,1);
set.seed(seednum);X23<-mvrnorm(n,rep(0,2),matrix(c(1,0.5,0.5,1),2,2))`
- 已编辑
明白楼主的意思了。
其实问题在于要深入理解一下R里set.seed()的工作原理:想象一个预先生成的随机序列,随机数生成器每次从这个序列头部开始,顺次读取随机数,并输出指定分布的随机数。set.seed()设定种子决定了所取头部的位置。
此时多个随机数函数顺次执行,生成的多个随机数向量是可重复的。
但是改变随机数函数执行顺序之后,随机数元序列顺序有变化,导致生成的随机数序列也不同
比较直观的例子如下, 经过尝试,rnorm生成随机数要消耗两个“元随机数”, runif消耗一个。
生成6个rnorm
和12个runif
之后, 新生成的runif(2,0,1)
就一样了。
set.seed(123)
rnorm(6,0,1)
#> [1] -0.56047565 -0.23017749 1.55870831 0.07050839 0.12928774 1.71506499
runif(2,0,1)
#> [1] 0.6775706 0.5726334
set.seed(123)
runif(12,0,1)
#> [1] 0.2875775 0.7883051 0.4089769 0.8830174 0.9404673 0.0455565 0.5281055
#> [8] 0.8924190 0.5514350 0.4566147 0.9568333 0.4533342
runif(2,0,1)
#> [1] 0.6775706 0.5726334
<sup>Created on 2022-06-14 by the reprex package (v2.0.1)</sup>
tctcab
好的呀,谢谢楼主耐心解答,我明白啦