In the absence of a reply, here's some code that solves what I presume is the typical "bringing back the future" problem. For each record, a missing value is replaced by the earliest following non-missing value, within the same group. This means of course that any group that ends with missing values will not have those values replaced:
data ds_missing_values;
infile datalines dlm=',';
input group $ var1 var2 var3;
datalines;
A, 1, 2, 3
A, ., 2, 5
A, 3, 4, .
A, 8, ., .
B, ., ., .
B, ., 2, 6
B, 3, 1, 8
C, 9, 4, 8
run;
data want (drop=_:);
set ds_missing_values (in=firstpass)
ds_missing_values (in=secondpass);
by group;
array var {3} var1-var3;
array history {3,20} _histv1_1-_histv1_20
_histv2_1-_histv2_20
_histv3_1-_histv3_20 ;
retain _: ;
if first.group then call missing(_f,_s,of _:);
_f+firstpass;
if firstpass then do _v=1 to 3;
history{_v,_f}=var{_v};
end;
if secondpass;
_s+secondpass;
call missing(history{1,_s},history{2,_s},history{3,_s});
if var1=. then var1=coalesce(of _histv1:);
if var2=. then var2=coalesce(of _histv2:);
if var3=. then var3=coalesce(of _histv3:);
run;
The program passes through eac group twice: the first time to build a history (up to 20 obs in this case) of values for VAR1, VAR2, and VAR3. The second pass will tap into that history, replacing a missing value with the earliest following non-missing (that's what the coalesce functiom does). Also during the second pass, current data in the history array is eliminated, so only future values are exposed to the coalesce functions.
... View more