Храните строки только по группам, для которых первым является определенное значение SAS - PullRequest
0 голосов
/ 31 января 2020

Я отсортировал данные как

ID value1 value2 
1    A       1
1    A       2
1    A       1
2    A       2
2    B       1
3    A       1
3    B       1
3    B       1 

Я хочу изменить эти данные на новый набор данных, где у меня есть только данные идентификаторов, последнее значение которых было BIe, это должно выглядеть так:

ID value1 value2 
2    A       2
2    B       1
3    A       1
3    B       1
3    B       1 

Я пытался

data want;
set have; 
by ID;
if last.value1 = 'B' then output;
run;

Но это не сработало. Может ли кто-нибудь помочь мне? Заранее спасибо!

Ответы [ 2 ]

2 голосов
/ 31 января 2020

Техника, известная как последовательный цикл DOW +, позволяет:

  • L oop по группе для вычисления некоторых переменных состояния. В этом случае переменная предназначена для отслеживания состояния является ли значение1 в последнем ряду группы = 'B' ?
  • Используйте переменную состояния, повторяя циклы по одной и той же группе, в соответствии с вашими критериями. В этом случае выведите строку, если требуется группа . Этот l oop основан на функции DO l oop, которая определяет границы один раз при инициализации l oop.

Исходные данные должны быть отсортированы по групповым переменным.

data want;
  do _n_ = 1 by 1 until (last.id);
    set have;
    by id;
  end;
  %* _n_ is group size at this point;

  _want_group = value1 = 'B';  %* state variable -- is B in last row?;

  do _n_ = 1 to _n_;   %* process the group again, using a different SET buffer;
    set have;          %* same data set as in the do/until;
                       %* no by required because loop limit _n_ is group size;
    if _want_group then
      OUTPUT;          %* output all rows of group as desired;
  end;

  drop _want_group;
run;
1 голос
/ 31 января 2020

Самый простой способ сделать это - выполнить несколько шагов. Первым шагом будет создание набора данных со всеми идентификаторами, для которых последним значением будет «B».

data tmp;
set have;
by ID value1;
if last.ID and value1='B' then output;
run;

Теперь в наборе данных tmp есть все необходимые идентификаторы, поэтому вы можете выбрать эти Идентификаторы из исходного набора данных.

proc sql;
create table want as
select *
from have
where id in (select distinct id from tmp);
quit;

Если вы хотите решить эту проблему за один шаг данных, то вы можете отсортировать исходную таблицу по убыванию значения 1 и выполнить следующий шаг данных.

proc sort data=have;
by id descending value1;
run;

data want(where=(keep_flag));
set have;
by id descending value1;
retain keep_flag;
if first.id and value1='B' then keep_flag=1;
else if first.id then keep_flag=0;
run;
...