Four methods of performing a look-ahead read
A question about determining whether the dates in two records are adjacent was posed to SAS-L.
As is frequently the case, the discussion quickly morphed to a related topic; in this case, how to do a look-ahead read.
I suggested the use of a second SET statement on the original data set, using the data set option FIRSTOBS=2. Richard DeVenezia submitted sample data and code using the BY statement; I submitted sample code that doesn't use a BY statement.
Here's the code to create the sample data:
data demo; input k $ val @@ ; cards; a 11 a 12 a 13 b 21 c 31 c 32 d 41 d 42 d 43 d 44 ;
Here's my code:
data lookahead1 (drop=nextk);
set demo end=endmain;
if not endnext then
set demo (firstobs=2
keep=k val
rename=(k=nextk val=nextval))
end=endnext;
if (k ne nextk) or endmain then
nextval = .;
run;
Here's Richard's code:
data lookahead2 (drop=i);
set demo;
by k;
if (first.k or not last.k) then
do i = 1 to 1 + (first.k and not last.k);
set demo(keep=val rename=(val=nextval) );
end;
if last.k then
nextval = .;
run;
Both methods produce the same output:
Obs k val nextval 1 a 11 12 2 a 12 13 3 a 13 . 4 b 21 . 5 c 31 32 6 c 32 . 7 d 41 42 8 d 42 43 9 d 43 44 10 d 44 .
Ed Heaton later posted a method, credited to Mike Rhoads, of using MERGE for the same effect, without the need to do a special check for the last observation:
Options mergeNoBy=noWarn ;
Data lookahead1( drop=nextk ) ;
Merge
demo
demo(
firstObs=2
rename=( k=nextK val=nextVal )
)
;
...
Run ;
Options mergeNoBy=error ;
Howard Schreier posted generalized code which looks ahead an arbitrary number of observations:
%let lookdepth = 2;
data lookahead&LOOKDEPTH(drop = many count close_to_last i);
do many = 1 by 1 until (last.k);
set demo(keep=k);
by k;
end;
do count = 1 to many;
set demo;
by k;
close_to_last = (many - count) < &LOOKDEPTH ;
if (first.k or not close_to_last) then
do i = 1 to 1 + first.k * min(&LOOKDEPTH,many-1);
set demo(keep=val rename=(val=ahead&LOOKDEPTH.val) );
end;
if close_to_last then do;
ahead&LOOKDEPTH.val = .;
end;
output;
end;
run;

0 Comments:
Post a Comment
<< Home