SAS (Base SAS)+
*=============================================================================;
* Create the input dataset;
*=============================================================================;
data lnms;
input usubjid visitnum score;
datalines;
101 1 20
101 2 .
101 3 30
102 1 90
102 2 10
102 3 .
102 4 .
;
run;
*=============================================================================;
* Sort the dataset by usubjid and visitnum;
*=============================================================================;
proc sort data=lnms;
by usubjid visitnum;
run;
*=============================================================================;
* Retain last non-missing score;
*=============================================================================;
data lnms01;
set lnms;
by usubjid visitnum;
retain last_score;
* Store the original score;
orig_score = score;
* Update the last non-missing score if present;
if not missing(score) then last_score = score;
* If missing, retain the previous value;
if missing(score) then score = last_score;
run;- To carry the most recent non-missing score forward until a new observed value appears, we use
RETAINtogether with amissing()check. - We start by sorting the dataset by subject and visit — SAS needs the BY order so that forward-fill means the same thing on every row.
retain last_score;keepslast_scorealive across rows instead of resetting to missing at each iteration.- We snapshot the incoming value into
orig_scorefirst so we can always see what was there before the fill. - When
scoreis non-missing, we updatelast_scorewith it. When it is missing, we replacescorewith the retainedlast_score— the classic "LOCF" (Last Observation Carried Forward) step. - After running, we confirm that missing scores have been replaced with the most recent prior non-missing score for the same subject, and
orig_scorestill shows the original NAs.