基于相同的种子复制 R 中 SAS (rancor) 中生成的随机法线?
Replicating random normal generated in SAS (rancor) in R, based on the same seed?
给定相同的种子,有没有办法在 R 中使用 rannor 函数生成在 SAS 中生成的完全相同的随机正态数?
我都测试了,好像没有。
data _null_;
CALL STREAMINIT(1245);
do i=1 to 10;
x2 = rand('NORMAL',0,1);
put x2;
end;
run;
/*
-1.295643934
0.0651085355
-0.391011151
1.1024205822
2.0712099724
-0.296163515
0.898941256
-0.584950901
0.2027164546
-0.986522152*/
set.seed(1245)
df<-rnorm(10,0,1)
df
[1] 0.41914007 -1.45583361 -1.45588008 -1.01564637 -0.53309914 -0.68360608 0.32590880
[8] 0.92256137 -0.05085288 0.29722361
要使这些匹配,您需要两件事:
- 用于生成随机数的种子
- 用于生成随机数的公式
SAS 用于 rannor
(我认为也用于 rand
,但我还没有看到对此的确认),以下算法(在 Psuedo-Random Numbers: Out of Uniform 中找到,由 Robert约翰逊和刘慧):
rannor_result = (−2* log(U1))**.5*cos(2*constant('pi')*U2)
其中 U1 和 U2 是统一号码流中的两个号码。 (也可以获得第二个数字,但据我所知,该数字已被丢弃。)
查看以下 SAS 数据步骤:
data test1;
U1 = ranuni(7);
U2 = ranuni(7);
X1 = (−2* log(U1))**.5*cos(2*constant('pi')*U2);
U1 = ranuni(7);
U2 = ranuni(7);
X2 = (−2* log(U1))**.5*cos(2*constant('pi')*U2);
run;
data test2;
x1 = rannor(7);
x2 = rannor(7);
run;
test1
和 test2
具有相同的随机数值。
我怀疑 R 和 SAS 是否共享通用的 PRNG 算法,尤其是 rannor
使用的算法不是很好(您应该使用 rand
,它使用 Mersenne Twister 会好得多).但是,您可以轻松地要求 SAS 输出它使用的种子——只要您输出 RANUNI 结果即可。
您可以要求 SAS 以这种方式执行此操作:
data rands_uni;
seed=7;
do _i_=1 to 10;
seed1 = seed;
call ranuni(seed,x1);
seed2=seed;
call ranuni(seed,x2);
output;
end;
run;
由此您可以在 R 中计算 rannor 结果(即,从 x1 和 x2)。我在那里包含了种子以供参考——也许 R 确实有能力使用它们。上面的论文确实引用了用于 ranuni
的 SAS 算法,但它也指出由于使用了一些更正(或者,可能是由于浮点精度问题?),您无法完美地复制它。
Proc IML;
Call RandSeed(6);
U1 = J(6,1);
U2 = J(6,1);
/* Weibull Distribution */
Call RandGen(U1,"WEIBULL",1.7737152,13.164695);
Print "Weibull Distribution:" U1;
/* Unifrom Distribution */
Call RandGen(U2,"UNIFORM",0,1);
Print "Uniform Distribution:" U2;
Submit/R;
set.seed(6);
## Weibull Distribution;
U1 <- rweibull(6,1.7737152,13.164695);
cat("Weibull Distribution:", U1, "\n");
## Uniform Distribution;
U2 <- runif(6,0,1);
cat("Unifrom Distribution:", U2, "\n");
EndSubmit;
Quit;
给定相同的种子,有没有办法在 R 中使用 rannor 函数生成在 SAS 中生成的完全相同的随机正态数?
我都测试了,好像没有。
data _null_;
CALL STREAMINIT(1245);
do i=1 to 10;
x2 = rand('NORMAL',0,1);
put x2;
end;
run;
/*
-1.295643934
0.0651085355
-0.391011151
1.1024205822
2.0712099724
-0.296163515
0.898941256
-0.584950901
0.2027164546
-0.986522152*/
set.seed(1245)
df<-rnorm(10,0,1)
df
[1] 0.41914007 -1.45583361 -1.45588008 -1.01564637 -0.53309914 -0.68360608 0.32590880
[8] 0.92256137 -0.05085288 0.29722361
要使这些匹配,您需要两件事:
- 用于生成随机数的种子
- 用于生成随机数的公式
SAS 用于 rannor
(我认为也用于 rand
,但我还没有看到对此的确认),以下算法(在 Psuedo-Random Numbers: Out of Uniform 中找到,由 Robert约翰逊和刘慧):
rannor_result = (−2* log(U1))**.5*cos(2*constant('pi')*U2)
其中 U1 和 U2 是统一号码流中的两个号码。 (也可以获得第二个数字,但据我所知,该数字已被丢弃。)
查看以下 SAS 数据步骤:
data test1;
U1 = ranuni(7);
U2 = ranuni(7);
X1 = (−2* log(U1))**.5*cos(2*constant('pi')*U2);
U1 = ranuni(7);
U2 = ranuni(7);
X2 = (−2* log(U1))**.5*cos(2*constant('pi')*U2);
run;
data test2;
x1 = rannor(7);
x2 = rannor(7);
run;
test1
和 test2
具有相同的随机数值。
我怀疑 R 和 SAS 是否共享通用的 PRNG 算法,尤其是 rannor
使用的算法不是很好(您应该使用 rand
,它使用 Mersenne Twister 会好得多).但是,您可以轻松地要求 SAS 输出它使用的种子——只要您输出 RANUNI 结果即可。
您可以要求 SAS 以这种方式执行此操作:
data rands_uni;
seed=7;
do _i_=1 to 10;
seed1 = seed;
call ranuni(seed,x1);
seed2=seed;
call ranuni(seed,x2);
output;
end;
run;
由此您可以在 R 中计算 rannor 结果(即,从 x1 和 x2)。我在那里包含了种子以供参考——也许 R 确实有能力使用它们。上面的论文确实引用了用于 ranuni
的 SAS 算法,但它也指出由于使用了一些更正(或者,可能是由于浮点精度问题?),您无法完美地复制它。
Proc IML;
Call RandSeed(6);
U1 = J(6,1);
U2 = J(6,1);
/* Weibull Distribution */
Call RandGen(U1,"WEIBULL",1.7737152,13.164695);
Print "Weibull Distribution:" U1;
/* Unifrom Distribution */
Call RandGen(U2,"UNIFORM",0,1);
Print "Uniform Distribution:" U2;
Submit/R;
set.seed(6);
## Weibull Distribution;
U1 <- rweibull(6,1.7737152,13.164695);
cat("Weibull Distribution:", U1, "\n");
## Uniform Distribution;
U2 <- runif(6,0,1);
cat("Unifrom Distribution:", U2, "\n");
EndSubmit;
Quit;