BookmarkSubscribeRSS Feed
☑ This topic is solved. Need further help from the community? Please sign in and ask a new question.
Batman
Quartz | Level 8

27 data a;
28 input x 1. y 1.;
29 list;
30 datalines;

RULE: ----+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0
31 11
32 43
33 43
NOTE: The data set WORK.A has 3 observations and 2 variables.
NOTE: DATA statement used (Total process time):
real time 0.01 seconds
cpu time 0.03 seconds

34 ;

35 run;
36
37 data b;
38 set a;
39 by x y;
40 /*only do the comparison after the first record*/
41 if _n_=1 then do;
42 cnt=1;
43 end;
44 else do;
45 if x=lag(x) and y le (lag(y)+4) then cnt+0;
46 else cnt+1;
47 end;
48 run;

2 The SAS System 15:20 Monday, November 6, 2023

NOTE: Missing values were generated as a result of performing an operation on missing values.
Each place is given by: (Number of times) at (Line):(Column).
1 at 45:31
NOTE: There were 3 observations read from the data set WORK.A.
NOTE: The data set WORK.B has 3 observations and 3 variables.
NOTE: DATA statement used (Total process time):
real time 0.00 seconds
cpu time 0.00 seconds

1 ACCEPTED SOLUTION

Accepted Solutions
Patrick
Opal | Level 21

Please note that the lag() function only queues a value if it executes. Using this function conditionally leads most of the time to undesired results.

Patrick_0-1699315771008.pnghttps://go.documentation.sas.com/doc/en/pgmsascdc/9.4_3.5/lefunctionsref/n0l66p5oqex1f2n1quuopdvtcjq... 

 

You get the missing note because the first time below code executes the lag() function will return a missing.

Patrick_1-1699315880523.png

 

I believe logic like below should return what you're after.

data b(drop=_:);
  set a;
  by x y;
  _lag_y=lag(y);
  /*only do the comparison after the first record*/
  if _n_=1 then
    do;
      cnt=1;
    end;
  else
    do;
      if not first.x and y le (_lag_y+4) then cnt+0;
      else cnt+1;
    end;
run;

 And stripping down your logic further below should still return the same result:

data b(drop=_:);
  set a;
  by x y;
  _lag_y=lag(y);
  if first.x or y le (_lag_y+4) then cnt+1;
run;

And even below would still work

data b(drop=_:);
  set a;
  by x y;
  cnt + ( first.x or y > sum(lag(y),4) );
run;

View solution in original post

1 REPLY 1
Patrick
Opal | Level 21

Please note that the lag() function only queues a value if it executes. Using this function conditionally leads most of the time to undesired results.

Patrick_0-1699315771008.pnghttps://go.documentation.sas.com/doc/en/pgmsascdc/9.4_3.5/lefunctionsref/n0l66p5oqex1f2n1quuopdvtcjq... 

 

You get the missing note because the first time below code executes the lag() function will return a missing.

Patrick_1-1699315880523.png

 

I believe logic like below should return what you're after.

data b(drop=_:);
  set a;
  by x y;
  _lag_y=lag(y);
  /*only do the comparison after the first record*/
  if _n_=1 then
    do;
      cnt=1;
    end;
  else
    do;
      if not first.x and y le (_lag_y+4) then cnt+0;
      else cnt+1;
    end;
run;

 And stripping down your logic further below should still return the same result:

data b(drop=_:);
  set a;
  by x y;
  _lag_y=lag(y);
  if first.x or y le (_lag_y+4) then cnt+1;
run;

And even below would still work

data b(drop=_:);
  set a;
  by x y;
  cnt + ( first.x or y > sum(lag(y),4) );
run;

hackathon24-white-horiz.png

2025 SAS Hackathon: There is still time!

Good news: We've extended SAS Hackathon registration until Sept. 12, so you still have time to be part of our biggest event yet – our five-year anniversary!

Register Now

How to Concatenate Values

Learn how use the CAT functions in SAS to join values from multiple variables into a single value.

Find more tutorials on the SAS Users YouTube channel.

SAS Training: Just a Click Away

 Ready to level-up your skills? Choose your own adventure.

Browse our catalog!

Discussion stats
  • 1 reply
  • 720 views
  • 1 like
  • 2 in conversation