Как создать переменные условной суммы по классу и идентификатору в SAS - PullRequest
0 голосов
/ 05 октября 2018

Из кумулятивного числа эпизодов (если временные интервалы меньше 10 дней, это считается одним эпизодом), я хочу вычислить «широкую» и «длинную» версию количества запущенных эпизодов на основе класса по идентификатору.

Вот так выглядят мои данные прямо сейчас.

id  Class   Date      Obsvn Episode_Sum
9   Wide    3/10/2012   1   1
9   Wide    3/12/2012   2   1
9   Wide    7/1/2012    111 2
9   Wide    7/3/2012    2   2
108 Wide    3/31/2011   1   1
108 Long    3/31/2011   1   1
108 Wide    4/17/2011   17  2
108 Wide    6/24/2011   68  3
108 Wide    6/16/2012   358 4
108 Wide    7/20/2012   34  5
108 Wide    7/27/2012   7   5

Я набрал количество операций по этому коду:

data want (drop=lag); set have;

by id date;

format lag mmddyy10.;
lag=lag(date);

if first.id then obsvn=1;
else obsvn=max(intck("Day", Lag, date),1);

if first.id then episode_sum=1;
else if obsvn>10 then episode_sum+1;

run;

Я хочу, чтобы мои данные выгляделиэто:

id  Class   Date     Obsvn Sum Wide Long
9   Wide    3/10/2012   1   1   1   0
9   Wide    3/12/2012   2   1   1   0
9   Wide    7/1/2012    111 2   2   0
9   Wide    7/3/2012    2   2   2   0
108 Wide    3/31/2011   1   1   1   0
108 Long    3/31/2011   1   1   1   1
108 Wide    4/17/2011   17  2   2   1
108 Wide    6/24/2011   68  3   3   1
108 Wide    6/16/2012   358 4   4   1
108 Wide    7/20/2012   34  5   5   1
108 Wide    7/27/2012   7   5   5   1

Но я получаю это:

id  Class   Date    Obsvn  Sum Wide Long
9   Wide    3/10/2012   1   1   1   0
9   Wide    3/12/2012   2   1   1   0
9   Wide    7/1/2012    111 2   2   0
9   Wide    7/3/2012    2   2   **1**   0
108 Wide    3/31/2011   1   1   1   **1**
108 Long    3/31/2011   1   1   1   1
108 Wide    4/17/2011   17  2   2   1
108 Wide    6/24/2011   68  3   3   1
108 Wide    6/16/2012   358 4   4   1
108 Wide    7/20/2012   34  5   5   1
108 Wide    7/27/2012   7   5   **1**   1

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

/*Calculating Long*/

if (first.id and class in ("Long")) then Episode_Long=1;
else if obsvn>10 and class in ("Long") then Episode_Long+1;
retain Episode_Long;

if (obsvn<10 and class in ("Long")) then Episode_Long=1;

if class not in ("Long") then do;
if first.id and class not in ("Long") then Episode_Long=0;
retain Episode_Long;
end;

/*Calculating Wide */

if (obsvn<10 and class in ("Wide")) then Episode_Wide=1   ;  
if (first.id and class in ("Wide")) then Episode_Wide=1;
else if obsvn>10 and class in ("Wide") then Episode_Wide+1;
retain Episode_Wide;

1 Ответ

0 голосов
/ 05 октября 2018

Сложность в том, что у вас есть две записи для одной и той же ДАТЫ во второй группе идентификаторов.Таким образом, вы хотите отслеживать это при расчете изменения в днях.

Вот один из способов.Сначала давайте введем ваши исходные данные (и желаемые результаты).

data have ;
  input id Class $ Date :mmddyy. EObsvn ESum EWide ELong ;
  format date yymmdd10.;
cards;
9   Wide    3/10/2012   1   1   1   0
9   Wide    3/12/2012   2   1   1   0
9   Wide    7/1/2012    111 2   2   0
9   Wide    7/3/2012    2   2   2   0
108 Wide    3/31/2011   1   1   1   0
108 Long    3/31/2011   1   1   1   1
108 Wide    4/17/2011   17  2   2   1
108 Wide    6/24/2011   68  3   3   1
108 Wide    6/16/2012   358 4   4   1
108 Wide    7/20/2012   34  5   5   1
108 Wide    7/27/2012   7   5   5   1
;

Возможно, вы захотите найти даты, когда вначале существуют разрывы WIDE или LONG.

data long ;
  set have ;
  by id date;
  where class='Long';
  if first.date;
  lag=lag(date);

  if first.id then call missing(lag,obsvn);
  else obsvn=max(intck("Day", Lag, date),1);
  lflag = missing(lag) or obsvn > 10 ;
  keep id date lflag ;

run;


data wide ;
  set have ;
  by id date;
  where class='Wide';
  if first.date;
  lag=lag(date);

  if first.id then call missing(lag,obsvn);
  else obsvn=max(intck("Day", Lag, date),1);
  wflag = missing(lag) or obsvn > 10 ;
  keep id date wflag ;

run;

Затем объедините их обратно наисточник по дате и рассчитать ваши счетчики.

data want ;
  merge have wide long ;
  by id date;

  if first.date then do ;
    lag=lag(date);
    format lag yymmdd10.;
    if first.id then call missing(lag,obsvn);
    else obsvn=max(intck("Day", Lag, date),1);
    retain lag obsvn;
  end;

  if first.id then call missing(sum,wide,long);
  if missing(lag) or obsvn > 10 then sum+first.date ;
  wide + (wflag and first.date);
  long + (lflag and first.date);

run;  

enter image description here

...