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

I want to create a subset from a data set to find records which meet a certain set of criteria (e.g. fieldA > 1,000 AND fieldB <1, etc...) AND include the record prior to those for each according to how the dataset is currently sorted.  How do I do that? In other words, if record number 100 fits the criteria, I want to include record 99, etc...  I want to retain the order of the data.

1 ACCEPTED SOLUTION

Accepted Solutions
data_null__
Jade | Level 19

 

 

data test;
   set sashelp.class(keep=age);
   if age eq 12 then do;
      grp = _n_;
      do point=_n_-1 to _n_;
         obs = point;
         set sashelp.class point=point;
         output;
         end;
      end;
   run;
proc print;
   run;

Capture.PNG

View solution in original post

5 REPLIES 5
data_null__
Jade | Level 19

 

 

data test;
   set sashelp.class(keep=age);
   if age eq 12 then do;
      grp = _n_;
      do point=_n_-1 to _n_;
         obs = point;
         set sashelp.class point=point;
         output;
         end;
      end;
   run;
proc print;
   run;

Capture.PNG

RandoDando
Pyrite | Level 9

That seemed to work and will work for the time being, but is there a way to modify it to avoid records being duplicated?  Seems as though if a record matches the criteria AND is prior to a record which does it shows up twice. 

Tom
Super User Tom
Super User

@RandoDando wrote:

That seemed to work and will work for the time being, but is there a way to modify it to avoid records being duplicated?  Seems as though if a record matches the criteria AND is prior to a record which does it shows up twice. 


In that case it might just be easier to do it two steps.  One to flag the records and then a second step to make the subset.  You can use one of the various methods for "looking ahead" to see if the next record matched the criteria.

data make_flag;
  set sashelp.class;
  match = (age=12);
run;

data want ;
  obsno+1;
  merge make_flag make_flag(firstobs=2 keep=match rename=(match=next_match));
  * DO NOT USE A BY STATEMENT ;
  if match or next_match;
run;

proc print;
run;

 

If the criteria depends only a few variables then just use the look ahead trick on those variables and you can do it in one pass.

data want ;
  obsno+1;
  merge sashelp.class sashelp.class(firstobs=2 keep=age rename=(age=next_age));
  * DO NOT USE A BY STATEMENT ;
  if (age=12) or (next_age=12);
run;
simonbun
Calcite | Level 5

You could keep track of whether the previous record has been output.

 

data test;
  set sashelp.class;
  if age eq 12 then do;
    if prevBeenOutput then output;
    else do;
      do point = max(_n_-1, 1) to _n_;
        set sashelp.class point=point;
        output;
      end;
      prevBeenOutput = 1;
    end;
  end;
  else prevBeenOutput = 0;

  retain prevBeenOutput;
  drop prevBeenOutput;
run;

hackathon24-white-horiz.png

The 2025 SAS Hackathon has begun!

It's finally time to hack! Remember to visit the SAS Hacker's Hub regularly for news and updates.

Latest Updates

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
  • 5 replies
  • 1138 views
  • 5 likes
  • 4 in conversation