Как добавить флаг на основе условия в предыдущих строках в SAS - PullRequest
0 голосов
/ 21 февраля 2020

У меня есть следующие данные, и я хотел бы добавить флаг к каждой строке, если в предыдущей строке выполняется условие.

В следующих данных мне нужен флаг = 1, если Cntr = S и только если следующей строкой является FE, а затем BC / AB C. Я не хочу, чтобы 2/8/2019 наблюдалось 101 и нет данных для 102, так как после FE нет никаких BC / AB C.

Имеют:

   id   Date        Evt      Cntr
  101  2/2/2019      FE         
  101  2/3/2019      BC      S 
  101  2/4/2019      FE
  101  2/5/2019      BC
  101  2/6/2019      FE
  101  2/7/2019      ABC
  101  2/8/2019      FE
  102  2/2/2019      FE

Хотите:

   id   Date        Evt      Cntr       flag
  101  2/2/2019      FE         
  101  2/3/2019      BC      S 
  101  2/4/2019      FE                  1
  101  2/5/2019      BC                  1 
  101  2/6/2019      FE                  1
  101  2/7/2019      ABC                 1  
  101  2/8/2019      FE
  102  2/2/2019      FE 

Я пытался использовать функции lag и retain для решения этой проблемы, но не получил то, что хотел. Пожалуйста, помогите !!

1 Ответ

0 голосов
/ 21 февраля 2020

Это еще один случай, когда обработка DOW может вычислить состояние пометки строки.

Массивы могут использоваться для отслеживания значений в группе. Массивы упрощают вычисление пометки нескольких регионов после S. Выберите размер массива, превышающий наибольший ожидаемый размер группы.

data have;
infile datalines missover;
attrib 
  id format=4. 
  date informat=mmddyy10. format=mmddyy10. 
  evt length=$3 
  cntr length=$1
;
input 
  id   Date        Evt      Cntr; datalines;
  101  2/2/2019      FE         
  101  2/3/2019      BC      S 
  101  2/4/2019      FE
  101  2/5/2019      BC
  101  2/6/2019      FE
  101  2/7/2019      ABC
  101  2/8/2019      FE
  102  2/2/2019      FE
  ;

data want;
  array evts[-1:1000] $3 _temporary_ ;
  array flags[1000] $1 _temporary_;

  call missing(of evts[*]);
  call missing(of flags[*]);

  do _n_ = 1 to dim(flags) until (last.id);

    set have;
    by id;

    evts[_n_] = evt;

    if cntr='S' then _s_index = _n_;

    if 0 < _s_index < _n_ - 1 then 
      if evt in ('BC', 'ABC') then 
        if evts[_n_-1] = 'FE' then 
          do ;
            flags[_n_] = '1';
            flags[_n_-1] = '1';
          end;
  end;

  if not last.id then do;
    put 'ERROR: ' id= 'group size larger than array size';
    stop;
  end;

  * apply flag value computed for each row of the group;
  do _n_ = 1 to _n_;
    set have;
    flag = flags[_n_];
    output;
  end;

  drop _:;
run;
...