SAS первое и последнее обследование, время схлопывается

Я застрял в одной задаче.

Теперь у меня есть переменная, называемая размещением, которая имеет две категории: вне дома и дома (здесь для краткости A и B). Кейс можно разместить в AAABAB последовательно. У каждого места размещения есть дата начала и дата окончания, например, 20.01.2015 - 21.02.2015 для первого A, 21.02.2015 - 8.05.2015 для второго A и т. Д.

Теперь я структурировал данные так: 111.1. (A как 1 и B как отсутствует). Как я могу совмещать время работы вне дома? То есть используйте дату начала первого A как дату начала, используйте дату окончания третьего A как дату окончания. Это будет первый период, когда пациент находится вне дома. Я думаю об использовании для этого цикла do. Но не могу понять, как это сделать.

Я думаю, что еще один способ сделать это - определить группы вне дома, например, AAABAABAAAA можно обозначить как 11123345555. Затем я могу использовать функцию PROC SQL, min и max, чтобы найти дату начала и дату окончания.

proc sql; создать таблицу comb как select *, min (strtdt) как minstrtdt, max (livarenddt) как maxenddt из группы limt по caseid, groupid; покидать;

Исходные данные, такие как (out указывает на отсутствие дома, 1 означает да,. Означает нет)

Obs caseid livarstrtdt livarenddt placemnt out

   81    00040903     14SEP2010     09DEC2010     01                   .
   82    00040903     09DEC2010     28FEB2011     02                   1
   83    00040903     28FEB2011     01APR2011     02                   1
   84    00040903     01APR2011     01JUL2011     02                   1
   85    00040903     01JUL2011     08AUG2012     02                   1
   86    00040903     08AUG2012     05NOV2014     02                   1
   87    00040903     05NOV2014     05NOV2014     03                   .
   88    00040903     12AUG2008     13AUG2008     12                   1
   89    00040903     13AUG2008     13AUG2008     01                   .
   90    00040903     13AUG2008     21AUG2008     01                   .

Я хочу получить такой результат,

Obs caseid livarstrtdt livarenddt placemnt out

   81    00040903     14SEP2010     09DEC2010     01                   .
   82    00040903     09DEC2010     05NOV2014     02                   1

   87    00040903     05NOV2014     05NOV2014     03                   .
   88    00040903     12AUG2008     13AUG2008     12                   1
   89    00040903     13AUG2008     13AUG2008     01                   .
   90    00040903     13AUG2008     21AUG2008     01                   .

У кого-нибудь есть идеи? Спасибо!!

ОБНОВИТЬ,

Теперь я изменил свои данные, caseid livaropnseq livarstrtdt livarenddt placemnt out

183  00040903      01        14SEP2010   09DEC2010   01                 .
184  00040903      01        09DEC2010   28FEB2011   02                 1
185  00040903      01        28FEB2011   01APR2011   02                 1
186  00040903      01        01APR2011   01JUL2011   02                 1
187  00040903      01        01JUL2011   08AUG2012   02                 1
188  00040903      01        08AUG2012   05NOV2014   02                 1
189  00040903      01        05NOV2014   05NOV2014   03                 .
190  00040903      02        12AUG2008   13AUG2008   12                 .
191  00040903      02        13AUG2008   13AUG2008   02                 1
192  00040903      02        13AUG2008   21AUG2008   02                 1

Как видите, ряды разных livaropnseq не следует объединять вместе. Например, строки 189 и 190, хотя случай находился дома в оба периода времени, они принадлежат разным livaropnseq (разные открытые последовательности). Как я могу включить эту переменную в код, чтобы не сжимать их вместе? Высоко оценен !!!

Результат должен быть таким: Obs caseid livaropnseq livarstrtdt livarenddt placemnt out

183  00040903      01        14SEP2010   09DEC2010   01                 .
184  00040903      01        09DEC2010   05NOV2014   02                 1
189  00040903      01        05NOV2014   05NOV2014   03                 .
190  00040903      02        12AUG2008   13AUG2008   12                 .
191  00040903      02        13AUG2008   21AUG2008   02                 1

ОБНОВЛЕНИЕ СНОВА, я ИСПОЛЬЗОВАЛ следующий код, чтобы НАКОНЕЦ получить то, что мне нужно!

data spell6;
set spell4;
by caseid livaropnseq out notsorted ;
group + first.out;
if first.caseid then group=1;
if first.out then startdt=livarstrtdt ;
retain startdt;
if last.out;
enddt = livarenddt ;
format startdt enddt date9.;
*drop livarstrtdt livarenddt ;
run;

Большое вам спасибо, ВСЕМ !! Я очень это оценил!


person Sophie    schedule 21.10.2016    source источник
comment
Вы можете показать нам свой код, пожалуйста?   -  person R.Rusev    schedule 21.10.2016
comment
У меня пока нет кодов, которые нужно показать, потому что я не могу понять, как использовать цикл do для этого.   -  person Sophie    schedule 21.10.2016
comment
Мой вопрос ясен? Спасибо!   -  person Sophie    schedule 21.10.2016
comment
Я только что добавил свой proc sql. Спасибо!   -  person Sophie    schedule 21.10.2016
comment
Нет, ваш вопрос непонятен. Добавьте образец того, как выглядят ваши данные, что вы хотите получить на выходе и что вы пробовали до сих пор.   -  person Reeza    schedule 21.10.2016
comment
Трудно понять ваш вопрос. Предложите вам добавить небольшой объем выборочных данных (5-10 записей с идентификаторами переменных, Placement, StartDate, EndDate) и желаемые выходные данные.   -  person Quentin    schedule 21.10.2016
comment
Всем большое спасибо! Я добавил сюда образец данных и нужные мне выходные данные.   -  person Sophie    schedule 21.10.2016


Ответы (3)


Вы можете сделать это на шаге DATA с помощью RETAIN и OUTPUT:

DATA dset2 (KEEP=caseid new_start new_stop new_out);
  SET dset1;
  BY caseid;
  RETAIN new_start new_stop new_out current_pl;
  IF first.caseid THEN DO;
    new_start=livarstrtdt;
    new_stop=livarenddt;
    new_out=out;
    current_pl=placemnt;
  END;
  ELSE IF placemnt=current_pl THEN new_stop=livarenddt;
  ELSE DO;
    OUTPUT;
    new_start=livarstrtdt;
    new_stop=livarenddt;
    new_out=out;
    current_pl=placemnt;
  END;
  IF last.caseid THEN OUTPUT;
RUN;

Сообщите мне, если я неправильно понял. В моем выводе не было бы obs 89, которого, похоже, не должно было быть в выводе.

РЕДАКТИРОВАТЬ: я обновил код, чтобы сохранить переменную «вне». Ниже мой результат:

caseid   new_start new_stop  new_out 
00040903 14SEP2010 09DEC2010 . 
00040903 09DEC2010 05NOV2014 1 
00040903 05NOV2014 05NOV2014 . 
00040903 12AUG2008 13AUG2008 1 
00040903 13AUG2008 21AUG2008 .

Если это не то, что вы хотите, будьте более ясны.

person Dave O    schedule 21.10.2016
comment
Но по какой-то причине я получил следующий вывод - person Sophie; 22.10.2016
comment
Obs caseid new_start new_stop out 47 00040903 14SEP2010 09DEC2010 1 48 00040903 09DEC2010 05NOV2014. 49 00040903 05 ноября 2014 г. 05 ноября 2014 г. 1 50 00040903 12 августа 2008 г. 13 августа 2008 г. 51 00040903 13AUG2008 21AUG2008. - person Sophie; 22.10.2016
comment
Даты кажутся неправильными, а также первая запись исчезла, что указывает на то, что дело находится дома ... Прошу прощения, я не знаю, как сделать вывод организованным .... - person Sophie; 22.10.2016
comment
@Sophie внесла свои изменения в исходный вопрос, а не в комментарий, и указала, что вы его обновили. - person Reeza; 22.10.2016
comment
Результат выглядит точно так же, как я ХОЧУ! Спасибо! - person Sophie; 22.10.2016
comment
Таким образом, в итоговой таблице сохраняются только вновь созданные переменные. Я включил старые переменные и сравнил их с вновь созданной переменной. Старые переменные уже не верны, верно? - person Sophie; 22.10.2016
comment
Правильно. Если вам нужны другие переменные, вы можете изменить шаг DATA или JOIN обратно с исходной таблицей. - person Dave O; 23.10.2016
comment
@DaveO Спасибо !!! Я сравнил ваши коды и коды Тома. В этом случае результаты такие же. но когда я обращаюсь ко всем своим случаям, результаты разные. Я пытаюсь понять, почему. Логика, лежащая в основе этих кодов, кажется мне правильной ... Вы так думаете? Спасибо!!! - person Sophie; 24.10.2016
comment
Я предполагаю, что это порядок исходных данных. Для обоих кодов данные должны быть отсортированы по caseid, а затем livarstrtdt. - person Dave O; 24.10.2016

Вы можете использовать опцию NOTSORTED в операторе BY на шаге DATA, чтобы SAS узнал, когда они меняют местоположение. Вы не сказали, что делать с дополнительной переменной PLACEMNT, поэтому этот код просто сохранит значение, которое он имел при последнем наблюдении в группе.

data have;
  input caseid $ livarstrtdt livarenddt placemnt $ out ;
  informat livarstrtdt livarenddt date9. ;
  format livarstrtdt livarenddt date9. ;
cards;
00040903 14SEP2010 09DEC2010 01 .
00040903 09DEC2010 28FEB2011 02 1
00040903 28FEB2011 01APR2011 02 1
00040903 01APR2011 01JUL2011 02 1
00040903 01JUL2011 08AUG2012 02 1
00040903 08AUG2012 05NOV2014 02 1
00040903 05NOV2014 05NOV2014 03 .
00040903 12AUG2008 13AUG2008 12 1
00040903 13AUG2008 13AUG2008 01 .
00040903 13AUG2008 21AUG2008 01 .
;;;;

data want ;
  set have ;
  by caseid out notsorted ;
  group + first.out;
  if first.caseid then group=1;
  if first.out then startdt=livarstrtdt ;
  retain startdt;
  if last.out;
  enddt = livarenddt ;
  format startdt enddt date9.;
  drop livarstrtdt livarenddt ;
run;

Результаты

Obs     caseid     placemnt    out    group      startdt        enddt
 1     00040903       01        .       1      14SEP2010    09DEC2010
 2     00040903       02        1       2      09DEC2010    05NOV2014
 3     00040903       03        .       3      05NOV2014    05NOV2014
 4     00040903       12        1       4      12AUG2008    13AUG2008
 5     00040903       01        .       5      13AUG2008    21AUG2008
person Tom    schedule 22.10.2016
comment
Большое Вам спасибо!!! Это очень полезно! Я могу получить желаемый результат. Единственное, что я также хочу, - могу ли я сохранить значение первого наблюдения, если он отсутствует (случай дома)? - person Sophie; 22.10.2016
comment
Или, когда кейс находится дома, мы сохраняем все строки и объединяем только те строки, которых нет дома. В этом примере результаты будут содержать 6 строк. Большое спасибо!!! . - person Sophie; 22.10.2016

data spell6;
set spell4;
by caseid livaropnseq out notsorted ;
group + first.out;
if first.caseid then group=1;
if first.out then startdt=livarstrtdt ;
retain startdt;
if last.out;
enddt = livarenddt ;
format startdt enddt date9.;
*drop livarstrtdt livarenddt ;
run;

СПАСИБО, ТОМ! и все остальные !!!

person Sophie    schedule 24.10.2016