Retain a variable value till condition is met

32 views Asked by At

I have dataset which has 3 variables which includes ID, date and enrol, and it is sorted by ID and date. My goal is to create a new dataset which has another variable say enrol_flag which should be 1 once the enrol is 1 but it should become 0 once enrol is 0 and retains that 0 value.

I am using SAS to program.

My dataset looks like:

ID  Date      enrol
1   01JAN21   0
1   O1FEB21   1
1   01MAR21   1
1   01APR21   1
1   01MAY21   0
1   01JUN21   0
1   01JUL21   1
1   01AUG21   1
2   01JAN21   1
2   O1FEB21   1
2   01MAR21   1
2   01APR21   1
2   01MAY21   1
2   01JUN21   0
2   01JUL21   0
2   01AUG21   0
3   O1FEB21   0
3   01MAR21   0
3   01APR21   0
3   01MAY21   0
3   01JUN21   0
3   01JUL21   1

Output I want

ID  Date      enrol  enrol_flag
1   01JAN21   0      0
1   O1FEB21   1      1
1   01MAR21   1      1
1   01APR21   1      1 
1   01MAY21   0      0
1   01JUN21   0      0
1   01JUL21   1      0
1   01AUG21   1      0
2   01JAN21   1      1
2   O1FEB21   1      1
2   01MAR21   1      1
2   01APR21   1      1
2   01MAY21   1      1
2   01JUN21   0      0
2   01JUL21   0      0
2   01AUG21   0      0
3   O1FEB21   0      0
3   01MAR21   0      0
3   01APR21   0      0
3   01MAY21   0      0
3   01JUN21   0      0
3   01JUL21   1      1

Thank you in advance for your help.

2

There are 2 answers

0
PeterClemmensen On

Try this

data have;
input ID Date :date7. enrol;
format Date date7.;
datalines;
1 01JAN21 0
1 01FEB21 1
1 01MAR21 1
1 01APR21 1
1 01MAY21 0
1 01JUN21 0
1 01JUL21 1
1 01AUG21 1
2 01JAN21 1
2 01FEB21 1
2 01MAR21 1
2 01APR21 1
2 01MAY21 1
2 01JUN21 0
2 01JUL21 0
2 01AUG21 0
3 01FEB21 0
3 01MAR21 0
3 01APR21 0
3 01MAY21 0
3 01JUN21 0
3 01JUL21 1
;

data want;
   set have;

   by ID Date;

   if first.ID then do;
      enrol_flag = enrol;
      d = 0;
   end;

   if enrol = 1 & d = 0 then do;
      enrol_flag = 1;
      d = 1;
   end;

   if enrol = 0 and d = 1 then enrol_flag = 0;

   retain enrol_flag d;
run;
0
Richard On

The sequences of enrol with in group id can form bands of 0's and 1's. You want to set flag to zero for every point after enrol transitions from 1 to 0, thus you need a secondary variable to track that case for enforcing the 0 rule.

Example (DOW loop):

data have;
input id date  enrol;
attrib date informat=date7. format=date7.;
datalines;
1   01JAN21   0
1   01FEB21   1
1   01MAR21   1
1   01APR21   1
1   01MAY21   0
1   01JUN21   0
1   01JUL21   1
1   01AUG21   1
2   01JAN21   1
2   01FEB21   1
2   01MAR21   1
2   01APR21   1
2   01MAY21   1
2   01JUN21   0
2   01JUL21   0
2   01AUG21   1
3   01FEB21   0
3   01MAR21   0
3   01APR21   0
3   01MAY21   0
3   01JUN21   0
3   01JUL21   1
;

data want (keep=id date enrol flag);
  do until (last.id);
    set have;
    by id;

    _d = dif(enrol); /* unconditional place ensures consistent dif */
    
    if first.id then flag=enrol;
    else
    if _d = -1 then _z = 1;  /* track transition 1 -> 0 */

    if _z
      then flag = 0;         /* enforce rule */
      else flag = enrol;

    output;
  end;
run;