重置随机数流
Reset random number stream
看来 SAS/IML 能够重置其随机数流 (doc link)。
SAS数据步骤中的随机数例程是否有类似的功能?
根据 this post,,似乎在单个数据步中忽略了对 streaminit
的后续调用。
例如,下面的代码为每一行生成不同的随机数:
data want;
do i = 1 to 2;
call streaminit(123); * <-- WANT THIS TO RESET THE STREAM;
ran1 = rand('uniform');
ran2 = rand('uniform');
ran3 = rand('uniform');
put _all_;
output;
end;
run;
输出:
i=1 ran1=0.5817000773 ran2=0.0356216603 ran3=0.0781806207
i=2 ran1=0.3878454913 ran2=0.3291709244 ran3=0.3615948586
我希望输出为:
i=1 ran1=0.5817000773 ran2=0.0356216603 ran3=0.0781806207
i=2 ran1=0.5817000773 ran2=0.0356216603 ran3=0.0781806207
不过,您可以使用生成的代码解决此问题,使用 CALL EXECUTE 或 DOSUBL,例如:
data _null_;
do i = 1 to 2;
rc=dosubl(cats("data want_",i,";
call streaminit(123); * <-- WANT THIS TO RESET THE STREAM;
ran1 = rand('uniform');
ran2 = rand('uniform');
ran3 = rand('uniform');
i=",i,";
put _all_;
output;
run;
"));
end;
rc = dosubl("data want; set want_1 want_2; run;");
run;
显然easier/better写一个宏来做这部分。
不幸的是,这是 'new' RAND 例程的一个限制;在这方面,旧的更容易使用(因为它实际上只有一颗种子)。新的种子属性比较复杂,所以虽然你可以用一个数字来初始化它,但它并不那么简单,因此很复杂。
您可以使用 call ranuni
为两个不同的随机数流使用相同的种子。
请注意,这使用了不同的劣质 PRNG,与 rand()
函数相比,其周期更短且统计特性更差。
示例:
data x;
seed1 = 123;
seed2 = 123;
do i =1 to 3;
call ranuni(seed1, x);
call ranuni(seed2, y);
output;
end;
run;
输出:
i=1 x=0.7503960881 y=0.7503960881
i=2 x=0.3209120251 y=0.3209120251
i=3 x=0.178389649 y=0.178389649
您无法在 SAS 9.4M4 中重置 RAND 函数的流。但是,您 可以 在 SAS 9.4M5 中倒回流(which shipped in Sep 2017) by using the new STREAMREWIND routine. 以下程序显示语法:
data want;
call streaminit(123);
do i = 1 to 2;
call streamrewind;
ran1 = rand('uniform');
ran2 = rand('uniform');
ran3 = rand('uniform');
put _all_;
output;
end;
run;
看来 SAS/IML 能够重置其随机数流 (doc link)。
SAS数据步骤中的随机数例程是否有类似的功能?
根据 this post,,似乎在单个数据步中忽略了对 streaminit
的后续调用。
例如,下面的代码为每一行生成不同的随机数:
data want;
do i = 1 to 2;
call streaminit(123); * <-- WANT THIS TO RESET THE STREAM;
ran1 = rand('uniform');
ran2 = rand('uniform');
ran3 = rand('uniform');
put _all_;
output;
end;
run;
输出:
i=1 ran1=0.5817000773 ran2=0.0356216603 ran3=0.0781806207
i=2 ran1=0.3878454913 ran2=0.3291709244 ran3=0.3615948586
我希望输出为:
i=1 ran1=0.5817000773 ran2=0.0356216603 ran3=0.0781806207
i=2 ran1=0.5817000773 ran2=0.0356216603 ran3=0.0781806207
不过,您可以使用生成的代码解决此问题,使用 CALL EXECUTE 或 DOSUBL,例如:
data _null_;
do i = 1 to 2;
rc=dosubl(cats("data want_",i,";
call streaminit(123); * <-- WANT THIS TO RESET THE STREAM;
ran1 = rand('uniform');
ran2 = rand('uniform');
ran3 = rand('uniform');
i=",i,";
put _all_;
output;
run;
"));
end;
rc = dosubl("data want; set want_1 want_2; run;");
run;
显然easier/better写一个宏来做这部分。
不幸的是,这是 'new' RAND 例程的一个限制;在这方面,旧的更容易使用(因为它实际上只有一颗种子)。新的种子属性比较复杂,所以虽然你可以用一个数字来初始化它,但它并不那么简单,因此很复杂。
您可以使用 call ranuni
为两个不同的随机数流使用相同的种子。
请注意,这使用了不同的劣质 PRNG,与 rand()
函数相比,其周期更短且统计特性更差。
示例:
data x;
seed1 = 123;
seed2 = 123;
do i =1 to 3;
call ranuni(seed1, x);
call ranuni(seed2, y);
output;
end;
run;
输出:
i=1 x=0.7503960881 y=0.7503960881
i=2 x=0.3209120251 y=0.3209120251
i=3 x=0.178389649 y=0.178389649
您无法在 SAS 9.4M4 中重置 RAND 函数的流。但是,您 可以 在 SAS 9.4M5 中倒回流(which shipped in Sep 2017) by using the new STREAMREWIND routine. 以下程序显示语法:
data want;
call streaminit(123);
do i = 1 to 2;
call streamrewind;
ran1 = rand('uniform');
ran2 = rand('uniform');
ran3 = rand('uniform');
put _all_;
output;
end;
run;