SAS - Сравнить наблюдения с предыдущими наблюдениями?

У меня есть следующие данные:

acct        date
11111       01/01/2014
11111       01/01/2014
11111       02/02/2014
22222       01/01/2014
22222       01/01/2014
33333       01/01/2013
33333       03/03/2014
44444       01/01/2014
44444       01/01/2014
44444       01/01/2014

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

Итак, для набора данных выше я хочу получить следующее:

acct        date
11111       01/01/2014
11111       01/01/2014
11111       02/02/2014
33333       01/01/2013
33333       03/03/2014

2 ответа

Решение

Нечто подобное будет работать. Сортируйте ваши данные по действию / дате, если еще нет, а затем проверьте каждый last.date строка. Если первый last.date строки тоже нет last.acctтогда это набор строк, в которые должен быть выведен респондент. Здесь я вывожу только одну строку для комбинации дата / действие:

data want;
set have;
by acct date;
if (last.date) and not (last.acct) then do;
  flg=1;
  output;
end;
else if last.date and flg=1 then output;
else if first.acct then flg=0;
run;

Если вам нужны все строки, то вам нужно либо взять вышеприведенное и объединить его с оригиналом, либо вы можете сделать цикл DoW:

data want;
do _n_=1 by 1 until (last.acct);
 set have;
 by acct date;
 if (last.date) and not (last.acct) then do;
  flg=1;
 end;
end;
do _t_ = 1 by 1 until (last.acct);
 set have;
 by acct date;
 if flg=1 then output;
end;
run;

Один PROC SQL сделает свое дело. Используйте счет (отдельную дату) для подсчета количества разных дат. Сгруппируйте это по acct, чтобы подсчитать по acct, и когда результат больше 1, отфильтруйте его, используя предложение has. Затем выберите acct и дату в качестве выходных столбцов.

Это специфическая обработка SAS для SQL. Большинство других реализаций не допускают эту конструкцию, когда вы не помещаете все неагрегированные столбцы из выбора в предложении group by.

proc sql noprint;
    create table _output as
    select acct, date format=ddmmyys10.
    from _input
    group by acct
    having count(distinct date) > 1
    order by acct, date;
   quit;
Другие вопросы по тегам