SAS Programming

DATA Step, Macro, Functions and more
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;

sas-innovate-white.png

Join us for our biggest event of the year!

Four days of inspiring keynotes, product reveals, hands-on learning opportunities, deep-dive demos, and peer-led breakouts. Don't miss out, May 6-9, in Orlando, Florida.

 

View the full agenda.

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