saslagretain

Update Baseline Value Based on Previous Rows


Every Subject has a baseline. Once the difference between the value and the baseline exceeds 5, that value becomes the baseline for all future comparisons until another value exceeds this new baseline by 5.

This is what I want the output data to look like: enter image description here

This is what I'm getting enter image description here

This is my current code, which gets me as close as anything I've tried. I've tried different combinations of retain, lag(), and ifn (suggested in this post)

Data Have;
 Input Visit usubjid Baseline Value;
 datalines;
1 1 112.2 112.2
2 1 112.2 113.7
3 1 112.2 112
3 1 112.2 108
4 1 112.2 109
5 1 112.2 107
7 1 112.2 106
8 1 112.2 107
; 
run;

proc sort;by usubjid;run;

data want;
 Length chg $71;
 retain chg;
 set Have;
 length prevchg $71;
 by usubjid;
 prevchg=chg;
 if first.usubjid then do; prevchg=''; end;
 baseline=ifn(prevchg in ('Increase >= 5mm New', "Decrease >= 5mm"),lag(value),lag(baseline));

 diff = value-baseline;
 if visit > 1 then do;
  if diff > 5 then do; chg='Increase >= 5mm New'; order = 3; end;
  else if diff < -5 then do; chg = 'Decrease >= 5mm'; order = 6; end;
  else if -5 <= diff <= 5 then do; 
    if prevchg in('Increase >= 5mm New', 'Increase > 5mm Persistent') then do; chg ='Increase > 5mm Persistent'; order = 4; end;
    else do; chg = 'No Change (change >= -5 and <= 5mm)'; order = 5; end;
  end;
 end;
run;

Right now the code will correctly update the baseline to the previous value for the next visit, but then goes right back to the original baseline. I'm confident this has something to do with the way Lag() and Retain work with if/then, but I cannot figure out the solution. here is an example of the issue:


Solution

  • You should be able to do this easily. The BASELINE variable CANNOT be on the input if you want to RETAIN its value.

    data want ;
      set have ;
      by usubjid;
      retain baseline;
      if first.usubjid then baseline=value;
      difference = baseline - value;
      output;
      if difference > 5 then baseline=value;
    run;