Given the same seed, is there a way to produce the exact same random normal numbers generated in SAS, using the rannor function, in R?
给定相同的种子,是否有办法在R中使用rannor函数生成在SAS中生成的完全相同的随机数?
3 个解决方案
#1
2
To make these match, you need two things:
要使这些匹配,你需要两样东西:
- The seed used to generate the random number
- 用来产生随机数的种子
- The formula used to generate the random number
- 用来生成随机数的公式
SAS uses for rannor
(and I think also for rand
, but I haven't seen confirmation of this), the following algorithm (found in Psuedo-Random Numbers: Out of Uniform, by Robert Johnson and Hui Liu):
SAS用于rannor(我认为也适用于rand,但我没有看到对此的证实),下面的算法(在Psuedo-Random Numbers: Out of Uniform, Robert Johnson and Hui Liu著):
rannor_result = (−2* log(U1))**.5*cos(2*constant('pi')*U2)
where U1 and U2 are two numbers from the uniform number stream. (A second number could also be obtained, but that number is discarded as far as I can tell.)
U1和U2是来自均匀数流的两个数。(也可以得到第二个数字,但据我所知,这个数字被丢弃了。)
See the following SAS datastep:
参见下面的SAS datastep:
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
and test2
have identical values for the rannorm numbers.
test1和test2对于rannorm数有相同的值。
I doubt that R and SAS share common PRNG algorithms, particularly as the one rannor
uses is not very good (you should use rand
which is much, much better, using a Mersenne Twister). However, you can easily ask SAS to output the seeds it used - as long as you output the RANUNI results.
我怀疑R和SAS是否共享常见的PRNG算法,特别是rannor使用的那个算法不是很好(您应该使用rand,使用Mersenne Twister会更好)。但是,您可以很容易地要求SAS输出它使用的种子——只要您输出RANUNI结果。
You can ask SAS to do that in this manner:
你可以让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;
From that you could then in R calculate the rannor result (ie, from x1 and x2). I include the seeds there for reference - perhaps R does have the ability to use them. The above paper does reference the algorithm SAS used for ranuni
, but it also states that you cannot replicate it perfectly due to some corrections used (or, perhaps, due to floating point precision issues?).
然后你可以用R计算rannor结果(即,从x1和x2)。我把种子包括在那里作为参考——也许R确实有能力使用它们。上面的文章确实引用了用于ranuni的算法SAS,但是它也指出,由于使用了一些修正(或者,可能是由于浮点精度问题),您无法完美地复制它。
#2
0
I test both, it seem it did not.
我两项都考了,好像没有。
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
#3
0
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;
#1
2
To make these match, you need two things:
要使这些匹配,你需要两样东西:
- The seed used to generate the random number
- 用来产生随机数的种子
- The formula used to generate the random number
- 用来生成随机数的公式
SAS uses for rannor
(and I think also for rand
, but I haven't seen confirmation of this), the following algorithm (found in Psuedo-Random Numbers: Out of Uniform, by Robert Johnson and Hui Liu):
SAS用于rannor(我认为也适用于rand,但我没有看到对此的证实),下面的算法(在Psuedo-Random Numbers: Out of Uniform, Robert Johnson and Hui Liu著):
rannor_result = (−2* log(U1))**.5*cos(2*constant('pi')*U2)
where U1 and U2 are two numbers from the uniform number stream. (A second number could also be obtained, but that number is discarded as far as I can tell.)
U1和U2是来自均匀数流的两个数。(也可以得到第二个数字,但据我所知,这个数字被丢弃了。)
See the following SAS datastep:
参见下面的SAS datastep:
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
and test2
have identical values for the rannorm numbers.
test1和test2对于rannorm数有相同的值。
I doubt that R and SAS share common PRNG algorithms, particularly as the one rannor
uses is not very good (you should use rand
which is much, much better, using a Mersenne Twister). However, you can easily ask SAS to output the seeds it used - as long as you output the RANUNI results.
我怀疑R和SAS是否共享常见的PRNG算法,特别是rannor使用的那个算法不是很好(您应该使用rand,使用Mersenne Twister会更好)。但是,您可以很容易地要求SAS输出它使用的种子——只要您输出RANUNI结果。
You can ask SAS to do that in this manner:
你可以让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;
From that you could then in R calculate the rannor result (ie, from x1 and x2). I include the seeds there for reference - perhaps R does have the ability to use them. The above paper does reference the algorithm SAS used for ranuni
, but it also states that you cannot replicate it perfectly due to some corrections used (or, perhaps, due to floating point precision issues?).
然后你可以用R计算rannor结果(即,从x1和x2)。我把种子包括在那里作为参考——也许R确实有能力使用它们。上面的文章确实引用了用于ranuni的算法SAS,但是它也指出,由于使用了一些修正(或者,可能是由于浮点精度问题),您无法完美地复制它。
#2
0
I test both, it seem it did not.
我两项都考了,好像没有。
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
#3
0
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;