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

Hello all. I have two columns, a name and a condition.

 

data person;
input name $ condition $;
datalines;
John "name not in ('Mary')"
Mary "name not in ('Jack', 'Bob')"
;

 

How do I use condition when looping through the data step? 

Below is some code that doesn't work but tries to get what I want.

 

data pass error;
set person;
call symput('criteria', condition);
if not(&criteria.) then output error;
else output pass;
run;

1 ACCEPTED SOLUTION

Accepted Solutions
Patrick
Opal | Level 21

If I understand right what you're trying to do then below should work.

data person;
  infile datalines truncover dsd dlm=' ';
  input name $ condition $100.;
  datalines;
John name not in ('Mary')
Mary name not in ('Jack', 'Bob')
;

filename codegen temp;
data _null_;
  file codegen;
  set person end=last;
  if _n_>1 then put 'else ' @;
  put 'if ' condition 'then output pass;';
  if last then put 'else output error;';
run;

data error pass;
  set person;
  %include codegen / source2;
run;

Generated code from SAS log:

45         data error pass;
46           set person;
47           %include codegen / source2;
NOTE: %INCLUDE (level 1) file CODEGEN is file 
      C:\Users\*****\AppData\Roaming\SAS\EnterpriseGuide\EGTEMP\SEG-11160-3cba2e81\contents\SAS Temporary 
      Files\_TD1604_SSAPAM3_\#LN00150.
48        +if name not in ('Mary') then output pass;
49        +else if name not in ('Jack', 'Bob') then output pass;
50        +else output error;
NOTE: %INCLUDE (level 1) ending.
51         run;

 

...but then looking at your sample data may be you want below code generated?

filename codegen temp;
data _null_;
  file codegen;
  set person end=last;
  _cond=condition;
  _cond=tranwrd(_cond,'name',cats("'",name,"'"));
  if _n_>1 then put 'else ' @;
  put 'if ' _cond 'then output pass;';
  if last then put 'else output error;';
run;

data error pass;
  set person;
  %include codegen / source2;
run;
47         data error pass;
48           set person;
49           %include codegen / source2;
NOTE: %INCLUDE (level 1) file CODEGEN is file 
      C:\Users\*****\AppData\Roaming\SAS\EnterpriseGuide\EGTEMP\SEG-11160-3cba2e81\contents\SAS Temporary 
      Files\_TD1604_SSAPAM3_\#LN00198.
50        +if 'John' not in ('Mary') then output pass;
51        +else if 'Mary' not in ('Jack', 'Bob') then output pass;
52        +else output error;
NOTE: %INCLUDE (level 1) ending.
53         run;

 

View solution in original post

3 REPLIES 3
Patrick
Opal | Level 21

If I understand right what you're trying to do then below should work.

data person;
  infile datalines truncover dsd dlm=' ';
  input name $ condition $100.;
  datalines;
John name not in ('Mary')
Mary name not in ('Jack', 'Bob')
;

filename codegen temp;
data _null_;
  file codegen;
  set person end=last;
  if _n_>1 then put 'else ' @;
  put 'if ' condition 'then output pass;';
  if last then put 'else output error;';
run;

data error pass;
  set person;
  %include codegen / source2;
run;

Generated code from SAS log:

45         data error pass;
46           set person;
47           %include codegen / source2;
NOTE: %INCLUDE (level 1) file CODEGEN is file 
      C:\Users\*****\AppData\Roaming\SAS\EnterpriseGuide\EGTEMP\SEG-11160-3cba2e81\contents\SAS Temporary 
      Files\_TD1604_SSAPAM3_\#LN00150.
48        +if name not in ('Mary') then output pass;
49        +else if name not in ('Jack', 'Bob') then output pass;
50        +else output error;
NOTE: %INCLUDE (level 1) ending.
51         run;

 

...but then looking at your sample data may be you want below code generated?

filename codegen temp;
data _null_;
  file codegen;
  set person end=last;
  _cond=condition;
  _cond=tranwrd(_cond,'name',cats("'",name,"'"));
  if _n_>1 then put 'else ' @;
  put 'if ' _cond 'then output pass;';
  if last then put 'else output error;';
run;

data error pass;
  set person;
  %include codegen / source2;
run;
47         data error pass;
48           set person;
49           %include codegen / source2;
NOTE: %INCLUDE (level 1) file CODEGEN is file 
      C:\Users\*****\AppData\Roaming\SAS\EnterpriseGuide\EGTEMP\SEG-11160-3cba2e81\contents\SAS Temporary 
      Files\_TD1604_SSAPAM3_\#LN00198.
50        +if 'John' not in ('Mary') then output pass;
51        +else if 'Mary' not in ('Jack', 'Bob') then output pass;
52        +else output error;
NOTE: %INCLUDE (level 1) ending.
53         run;

 

Ksharp
Super User
data person;
infile cards dsd dlm=' ';
input name $ condition : $30.;
datalines;
John "name not in ('Mary')"
Mary "name not in ('Jack', 'Bob')"
;

data _null_;
set person;
call execute(cat('data pass error;set person; if ',condition,' then output error;else output pass;run;'));
run;
Tom
Super User Tom
Super User

The CODE of the data step is compiled BEFORE the step starts running.  So you cannot reference the value of a macro variable created while the step is running  to change the code since you are already past that point in time.

 

If you want to use DATA as CODE then the easiest thing is to write it to a code that that you can %INCLUDE.

 

I could not make any sense out of your example so here is a slightly different one that uses TWO datasets, one with the conditions and another which is the data that will be evaulated.

data conditions;
  infile datalines dsd dlm=' ';
  input result $ condition :$40.;
datalines;
AAA "name in ('Mary')"
BBB "name in ('Jack', 'Bob')"
;

data person;
  input name $;
datalines;
Mary
Jack
Bob
Fred
;

So convert the conditions into code.  Perhaps a series of IF/THEN/ELSE statements?

filename code temp;
data _null_;
  file code;
  set conditions;
  if _n_>1 then put 'else ' @;
  put 'if (' condition ') then ' result= $quote. ';' ;
run;

Then use that code in a data step.

data want;
  set person;
%include code / source2;
run;

Result

Obs    name    result

 1     Mary     AAA
 2     Jack     BBB
 3     Bob      BBB
 4     Fred

 

 

SAS Innovate 2025: Call for Content

Are you ready for the spotlight? We're accepting content ideas for SAS Innovate 2025 to be held May 6-9 in Orlando, FL. The call is open until September 25. Read more here about why you should contribute and what is in it for you!

Submit your idea!

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.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

Discussion stats
  • 3 replies
  • 295 views
  • 3 likes
  • 4 in conversation