SAS (Base SAS)+
*==============================================================================;
* Create the input dataset;
*==============================================================================;
data pmax;
input usubjid visitnum score;
datalines;
101 1 20
101 2 .
101 3 30
102 1 90
102 2 10
102 3 .
102 4 91
102 5 .
;
run;
*==============================================================================;
* Sort the dataset by usubjid and visitnum;
*==============================================================================;
proc sort data=pmax;
by usubjid visitnum;
run;
*==============================================================================;
* Retain previous non-missing low score;
*==============================================================================;
data pmax01;
set pmax;
by usubjid visitnum;
retain maxscore;
* Store the original score;
orig_score = score;
if first.usubjid then maxscore = .;
*Store maximum score and assign maxscore when score is missing;
if not missing(score) then maxscore = max(score,maxscore);
else score=maxscore;
run;- This is the mirror image of the running-minimum pattern — we carry forward the largest score seen so far within each subject.
- After sorting by subject and visit, we reset
maxscoreat the start of each subject withif first.usubjid then maxscore = .;. - On every non-missing row, we update
maxscore = max(score, maxscore). SAS treats missingmaxscoreas smaller than any real number, so the first non-missing score becomes the starting maximum naturally. - On missing-score rows we substitute
score = maxscore, which fills the NA with the running high. - We keep
orig_scoreso the original NAs remain visible after the fill. - After running, we verify
maxscorenever decreases within a subject and missing rows now carry the running maximum.