重置随机数流

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;