SAS中无重复的随机数生成

时间:2018-09-16 11:11:06

标签: sas

我正在尝试不重复地获得随机数。我的想法是做while循环,它将进行5次。在内部,我将获得随机数,将其存储在表中,并在每次迭代时检查所选择的数字是否在表中,然后确定此随机选择是否为重复项。

这是我尝试执行我的想法的代码,但是出了点问题,我不知道自己在哪里出错。

DataType

2 个答案:

答案 0 :(得分:3)

想要随机排列的声音。

165  data _null_;
166     seed=12345;
167     array r[5] (1:5);
168     put r[*];
169     call ranperm(seed,of r[*]);
170     put r[*];
171     run;

1 2 3 4 5
5 1 4 3 2

这是您要执行的操作的简化版本。

data WithoutRepetition;
   i=0;
   array temp[5];
   do r=1 by 1 until(i eq dim(temp));
      rand=round(4*ranuni(0)+1,1);
      if rand not in temp then do; i+1; temp[i]=rand; end;
      end;
   drop i rand;
   run;

enter image description here

答案 1 :(得分:1)

如果有一个令人费解的解决方案,您就可以接近了。出于教育目的,尽管数据_null_的答案要干净得多,但这是您的代码无法正常工作的原因:

  • 您的请假语句位于另一个do循环内的do-end块内。离开语句仅脱离最内部的do循环,因此您的语句无效。
  • 您的continue语句也是如此,其中第一个完全没有必要。
  • 因为您要使用新找到的唯一值更新数组,所以在您增加counter之前 ,先前填充的值将被覆盖。这通常会导致覆盖值的重复出现在输出中。

我会将continueleavegoto放在同一个类别中-尽可能避免使用它们,因为它们往往会使代码难以调试。在入口点为所有循环设置退出条件更加清楚。

不过,这只是为了好玩,这是原始代码的固定版本:

data WithoutRepetition;
  counter = 0;
  array temp (5)  _temporary_;
  do while(1);
    rand=round(4*ranuni(0) +1,1);

    if counter = 0 then do;
      temp(1) = rand;
      counter +1;
      output;
    end;

    dupe = 0;
    do a=1 to counter;
      if temp(a) = rand then dupe=1;
    end; 

    if dupe then continue;

    counter +1;
    temp(counter) = rand;
    output;
    if counter = 5 then leave;  
  end;    
run;

这是一个等效版本,其中所有leavecontinue语句都替换为更具可读性的替代方案:

data WithoutRepetition;
  counter = 0;
  array temp (5)  _temporary_;
  do while(counter < 5);
    rand=round(4*ranuni(0) +1,1);

    if counter = 0 then do;
      temp(1) = rand;
      counter +1;
      output;
    end;

    else do;
      dupe = 0;
      do a=1 to counter while(dupe = 0);
        if temp(a) = rand then dupe=1;
      end; 

      if dupe = 0 then do;
        counter +1;
        temp(counter) = rand;
        output;
      end;
    end;

  end;    
run;