The same problem can be solved with SQL. But it may have a performance issue.
A data step is much faster.
Replacing tmpy[i]=1e308; ---> tmpy[i]=-1e308;
and min=tmpy[1]; ---> max=tmpy[&k];
will get max in the previous k rows in each group.
%let group=20000;
%let maxn=1000;
%let k=200;
data t1;
do g=1 to &group;
n=ceil(ranuni(123)*&maxn);
do i=1 to n;
x=ceil(rannor(123)*&maxn);
output;
end;
end;
keep g x;
run;
data t2;
array tmpx(10000) _temporary_ ;
array tmpy(&k) _temporary_ ;
do until(last.g);
set t1;
by g;
if first.g then cnt=0;
cnt+1 ;
tmpx[cnt]=x;
k=0;
do i=1 to &k;
tmpy[i]=1e308;
end;
do i=max(cnt-&k+1,1) to cnt;
k+1;
tmpy[k]=tmpx[i];
*put tmpy[k]=;
end;
call sortn(of tmpy[*]);
min=tmpy[1];
output;
end;
keep x g min;
run;