использование цикла do для макроса

Я разместил это раньше и получил помощь. Мой интерес был возбужден, и я рискнул немного углубиться в это, чтобы посмотреть, что я могу с этим сделать. Я увлечен симуляциями, но я всего лишь средний программист 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 нападающих.

.73 .75 .72 .78 .81 .69 .74 .72 .75

С помощью Джо и других все вышеперечисленное сделало то, что я хотел, а именно имитировал в первую очередь подсчет аутов в ОДНОЙ бейсбольной игре.

Я играл с этим (безрезультатно) и пытался заставить его повторить игру, так сказать, где она начиналась бы в верхней части состава после 27 аутов. Итак, для того, что у меня есть прямо сейчас, предположим, что 27-й аут достигается с 5-м тестом. Я хотел бы поместить весь этот код в цикл, где он снова запускает процесс в начале набора данных (1-е наблюдение, то есть первое тестовое средство). Итак, предположим, я хочу выполнить здесь 3 итерации. 3 игры по 27 аутов. Есть ли способ сделать это? Я пробовал сделать следующее.

%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 раза требуется второе наблюдение из набора данных и т. Д.

Выходы randvar cutoffouts_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

Кто-нибудь может помочь? Я понимаю, что это немного выходит за рамки того, что обычно обсуждается здесь, но некоторые из моих учеников также интересуются симуляциями, и пример с бейсболом их определенно заинтересовал. Это стало забавной задачей. спасибо, что зашли так далеко.


person GKJohn    schedule 08.09.2017    source источник


Ответы (1)


Вам не нужен макрос. Вы должны иметь возможность добавить внешний цикл 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;
person Quentin    schedule 09.09.2017