Several publishings and code examples have been published on LAG() function in SAS. However, if one looks for a LEAD function, there is nothing documented in the language reference. However, there are some ideas published in SAS conference papers using POINT= and a few other methods. This article shows a simple way to shift the values ahead to get the leading values and also show the LAG() values beside the original value with an example.
/* one way to simulate an opposite of a LEAD() function in SAS */
DATA in;
INPUT X $1. @@; if X ne ' ';
DATALINES;
12345
;
run;
data leadx(rename=x=LEADX);
set in;
if _n_>1;
run;
data out;
set in;
set leadx;
LAGX=lag1(x);
run;
PROC PRINT DATA=out NOOBS;
var lagx X LEADX;
TITLE 'SIMULATION OF A MISSING LEAD FUNCTION';
RUN;
This code generated an output that is shown for the readers' reference:
SIMULATION OF A MISSING LEAD FUNCTION
LAGX X LEADX
. 1 2
1 2 3
2 3 4
3 4 5
For other ideas to simulate LEAD() function, see:
How would this be extended if you had a BY group variable?
Have been caught up.... couldn't respond sooner. I apologize. ....
To Reeza's point, a bit of customization would be needed to tailor the By group variable requirement but should be doable.....
To Quentin's observation - a good catch..Thanks for presenting it. I have a variation presented below, hope it helps.
DATA in;
INPUT X $1. @@; if X ne ' ';
DATALINES;
12345
;
run;
DATA NEWX;
SET IN END=LAST;
LAGX=LAG(X);
OUTPUT;
IF LAST
THEN
DO;
LAGX=X;
X=.;
OUTPUT;
END;
RUN;
DATA NEWX ;
SET NEWX;
IF _N_ = 1
THEN
DELETE;
LAGX2=LAG(LAGX);
RUN;
PROC DATASETS NOPRINT;
MODIFY NEWX;
RENAME X=LEADX
LAGX=X
LAGX2=LAGX;
RUN;
PROC PRINT;
RUN;
Generates the following output... just for reference...
Obs LEADX X LAGX
1 2 1
2 3 2 1
3 4 3 2
4 5 4 3
5 . 5 4
Thanks again...!!!
Kannan Deivasigamani.
/* prepare sample data */
data a; do x=1 to 5; output; end; run;
/* lead */
data b;
set a end=end;
leadX = x;
x = lag(x);
if _n_>1 then output;
if end then do; x=leadx; leadx=.; output; end;
run;
Read-ahead merge seems far easier.
ie:
data want;
merge have(rename=x=lagx) have(firstobs=2 in=_base) have(firstobs=3 rename=x=leadx));
if _base;
run;
You can use BY group processing to handle groups. You can use the trick of adding back empty observations on the "lead" stream do avoid stopping the data step when you read past the end of the data.
Here is an example using SASHELP.CLASS where we will treat SEX as the group variable and AGE the variable to find lag and lead values.
proc sort data=sashelp.class out=have ;
by sex name;
run;
data want ;
set have(keep=sex name age);
by sex;
age_lag = lag(age);
set have(keep=age rename=(age=age_lead) firstobs=2) have(drop=_all_ obs=1);
if first.sex then call missing(age_lag);
if last.sex then call missing(age_lead);
run;
Obs Name Sex Age age_lag age_lead 1 Alice F 13 . 13 2 Barbara F 13 13 14 3 Carol F 14 13 12 4 Jane F 12 14 15 5 Janet F 15 12 11 6 Joyce F 11 15 14 7 Judy F 14 11 12 8 Louise F 12 14 15 9 Mary F 15 12 . 10 Alfred M 14 . 14 11 Henry M 14 14 12 12 James M 12 14 13 13 Jeffrey M 13 12 12 14 John M 12 13 16 15 Philip M 16 12 12 16 Robert M 12 16 15 17 Ronald M 15 12 11 18 Thomas M 11 15 15 19 William M 15 11 .
There's a page on the old sascommunity.org page that describes four methods of doing look-ahead reads.
http://www.sascommunity.org/wiki/Four_methods_of_performing_a_look-ahead_read
Join us for SAS Innovate 2025, our biggest and most exciting global event of the year, in Orlando, FL, from May 6-9.
Lock in the best rate now before the price increases on April 1.
Data Literacy is for all, even absolute beginners. Jump on board with this free e-learning and boost your career prospects.