BookmarkSubscribeRSS Feed
scify
Obsidian | Level 7

Apologies if there's an obvious answer to this, but I haven't been able to find it.

Let's say I have a macro variable:

 

%macro do_thing(var);
    <insert code doing things based on &var here>
%mend do_thing;

%do_thing(1);
%do_thing(2);
%do_thing(3);
....
%do_thing(9);

And I also have a list of values stored in a macro variable:

%let list_var = 1,2,5,7,9;

If I wanted part of the code in %do_thing to execute only if the value of &var was one of the values in &list_var, how would I do that? My naive expectation would be something like:

%macro do_thing(var);
    <insert code doing things based on &var here>
    %if &var %in (&list_var) %then %do;
         <insert &list_var-specific code here>
    %end;
%mend do_thing;

But %in doesn't seem to exist.

 

2 REPLIES 2
Tom
Super User Tom
Super User

If you want the macro processor to treat IN as an operator and not just some random two byte string you need to set MINOPERATOR system option (and the MINDELIMITER option also).

 

If you are doing it inside a macro then use the MINOPERATOR and MINDELIMITER options of the %MACRO statement so that your macro does not change behavior when users change the system options.  The parentheses are not needed, but usually do not cause any trouble.

%macro do_thing(var) / minoperator mindelimiter=',' ;
    <insert code doing things based on &var here>
    %if &var in &list_var %then %do;
         <insert &list_var-specific code here>
    %end;
%mend do_thing;

You could also just use the INDEXW() or FINDW() function to test if the value appears in the string.  Use %SYSFUNC() to use them in macro logic.

 

You coding will be much easier if the values are delimited by something other than comma in the list.  That way you could more easily pass the list of values into the macro as a parameter If you have commas in the value you will need to use macro quoting to pass the value as an argument.

%macro doit(value,list) / minoperator mindelimiter=' ';
%if &value in &list %then %put &=value IS in &=list;
%else %put &=value IS NOT in &=list;
%mend doit;

%doit(value=1,list=1 2 5 7 9);

 

Remember that in the SAS language you can use spaces instead of commas when using the IN operator.  So code like this in normal SAS code works:

if a in (1 3 5 7) then do;

end;

 

PaigeMiller
Diamond | Level 26

%inm does exist (In-Macro) as a macro you can include in your code.

 

%macro inm(slist,s);
    /* SAS Macro %inm to see if &s is contained in a string or list &slist                 */
    /* Borrowed from https://groups.google.com/forum/#!topic/comp.soft-sys.sas/fWcSDgg11tE */
    %if %sysfunc(indexw(&slist,&s)) gt 0 %then 1 ;
    %else 0;
%mend;

 

Example of use:

 

%let list=1 2 3 5 7;
%let target = 22;
%let abc=%inm(&list,&target);
%put &=abc;

%let target = 5;
%let abc=%inm(&list,&target);
%put &=abc;

 

 

--
Paige Miller

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
  • 2 replies
  • 501 views
  • 0 likes
  • 3 in conversation