使用do循环的宏

时间:2017-09-08 20:58:40

标签: sas sas-macro

我之前发布了这个,并得到了帮助。我的兴趣被激发了,我进一步探究了这一点,看看我能用它做些什么。我对模拟很着迷,但我只是一名普通的SAS程序员。我想知道是否有人可以在这里提供帮助。

data out;
  call streaminit(7);           *seed better random number engine;
  do pointvar = 1 by 1 until (outs=27);   *iterate starting at         
  1 and stop when 27 outs ;
    randvar = rand('Uniform');  *better random number engine;
    if pointvar > 9 then pointvar=1;      *reset to 1 if over 9;
    set in point=pointvar;      *pull the row we need;
    if randvar < cutoff then do;
      outs+1;
      outs_inning+1;
    end;
    output;
    if outs_inning=3 then outs_inning=0;
  end;
  stop;
run;

数据集只有9个击球手的观察结果。

0.73 0.75 0.72 0.78 0.81 0.69 0.74 0.72 0.75

在乔和其他人的帮助下,上面做了我想要的,主要是模拟一场棒球比赛中的出局计数。

我一直在玩这个(无济于事)并试图让它重复一场比赛,可以这么说,它会在27场比赛后从阵容的顶端开始。所以对于我现在所拥有的,假设第5次击球是通过第5击球手实现的。我想把这整个代码放在一个循环中,它在数据集的开头再次启动进程(第一次观察,即第一次击球)。 所以,假设我想在这里完成3次迭代。 27场比赛的3场比赛。有没有办法做到这一点?我尝试过以下操作。

%macro replicate(new,out,n)/des=’&new1 is &out repeated &n times 

Data &new; 

%do i=1 to &n; 

  Set &out; 

Output; 

%end; 

%mend; 

%replicate(new,out,3); 

Proc print; 

我希望有一个do语句我能做到这一点,但问题在于它正在阅读每次观察3次。所以在do i = 1到3之后,然后设置(三个实例从数据集'out'进行第一次观察,然后3次从数据集中进行第二次观察,等等。  即

Outs randvar cutoff outs_inning

0 0.84 0.73 0

0 0.84 0.73 0

0 0.84 0.73 0

1 0.61 0.75 0

1 0.61 0.75 0

1 0.61 0.75 0

有人可以帮忙吗?我感谢这有点超出了这里通常讨论的范围,但我的一些学生也对模拟感兴趣,而棒球的例子肯定对他们感兴趣。它已成为一个有趣的问题。谢谢你让我这么远。

1 个答案:

答案 0 :(得分:0)

您不需要宏。您应该能够添加一个外部DO循环do game=1 to 3;

下面我将变量POINTVAR更改为BATTER,并添加了一个PUT语句将消息写入日志。

data in;
  input cutoff @@;
  cards;
.73 .75 .72 .78 .81 .69 .74 .72 .75
;

data play;
  call streaminit(7);

  do game=1 to 3;
    outs=0; 
    outs_inning=0;
    do batter = 1 by 1 until (outs=27);
      randvar = rand('Uniform');
      if batter > 9 then batter=1;
      set in point=batter;
      if randvar < cutoff then do;
        outs+1;
        outs_inning+1;
      end;
      output;
      put (game batter cutoff randvar outs_inning outs)(=);
      if outs_inning=3 then outs_inning=0;
    end;
  end;
  stop;
run;