Retain a variable value till condition is met

55 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 best solutions below

0
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
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;