BookmarkSubscribeRSS Feed
ChrisNZ
Tourmaline | Level 20

Consider this:

%macro t  / minoperator;
  %if 1=1 %then %put a;
  %if 1 in 1 2 %then %put b;
  %if 1=1 & 2=2 %then %put c;
  %if 1 in 1 2 & 2=2 %then %put d;
  %if 1 in 1 2 & 2>2 %then %put e;
  %if 1 in 1 2 and 2>2 %then %put f;
%mend; 
%t

The output is:

a
b
c
d
e

 

e should not be here right?

The IN operator discounts and as a keyword, but counts & as a string in the list.

 

Now I know, and you too if you didn't already.

 

 

6 REPLIES 6
Ksharp
Super User
/*
Chris ,
You are right .
It seems that '&' is a value for IN operator
You need '()' to tell SAS the range of operator.
That also tells us it always righ to use '()' 
to define range of operator.
Like this :
*/

%macro t  / minoperator mindelimiter=' ' ;
  %if 1=1 %then %put a;
  %if 1 in 1 2 %then %put b;
  %if 1=1 & 2=2 %then %put c;
  %if 1 in 1 2 & 2=2 %then %put d;
  %if (1 in 1 2) & (2>2) %then %put e;
  %if 1 in 1 2 and 2>2 %then %put f;
%mend; 
%t
79   /*
80   Chris ,
81   You are right .
82   It seems that '&' is a value for IN operator
83   You need '()' to tell SAS the range of operator.
84   That also tells us it always righ to use '()'
85   to define range of operator.
86   Like this :
87   */
88
89   %macro t  / minoperator mindelimiter=' ' ;
90     %if 1=1 %then %put a;
91     %if 1 in 1 2 %then %put b;
92     %if 1=1 & 2=2 %then %put c;
93     %if 1 in 1 2 & 2=2 %then %put d;
94     %if (1 in 1 2) & (2>2) %then %put e;
95     %if 1 in 1 2 and 2>2 %then %put f;
96   %mend;
97   %t
a
b
c
d

Tom
Super User Tom
Super User

You could also just add the parentheses around the list of values.

  %if 1 in (1 2) & 2>2 %then %put e;

It never made sense to me why you would do that since the IN operator in macro code does not require it, unlike in regular SAS code.  But it does help let the parser know where the list starts and ends.

Quentin
Super User

I didn't know, and think maybe it's worth submitting as a bug.

 

Honestly, there were so many problems in implementing the macro IN operator in the beginning, I've stayed away from it.  

 

I agree with your diagnosis: if you don't put parentheses around the argument, the IN operator will treat & and also | as strings, but will treat AND and OR as operators that end the argument.   Another test case:

 

%macro t  / minoperator;
  %put 1 in 0 & 1 evaluates to: %eval(1 in 0 & 1) ;     *Returns 1 but should return 0 ;
  %put 1 in 0 and 1 evaluates to: %eval(1 in 0 and 1) ; *Returns 0 ;

  %put 0 in 1 | 0 evaluates to: %eval(0 in 1 | 0) ;     *Returns 1 but should return 0 ;
  %put 0 in 1 or 0 evaluates to: %eval(0 in 1 or 0) ;   *Returns 0 ;
%mend; 

%t

It looks to me like the AND is capable of ending the list of arguments to the IN operator.  Below reasonably errors, because SAS can't evaluate the expression 0 1:

%macro t  / minoperator;
  %put  %eval(1 in 0 and 0 1 ) ; *errors, sensibly ;
%mend; 
%t

 

But the below executes, and the only way that happens is if the & operator was sucked into the list of arguments for IN:

%macro t  / minoperator;
  %put  %eval(1 in 0 & 0 1 ) ;  *returns 1 ;
%mend; 
%t

 

ChrisNZ
Tourmaline | Level 20

@Ksharp Yes 

%if (1 in 1 2) & (2>2) %then %put e;

is the cleanest imho

 

@Tom  Good point, though I don't think I'll use the syntax

%if 1 in (1 2) & 2>2 %then %put e;

The parentheses look like they are part of the string values to test. This is confusing to me.

@PeterClemmensen Thank you!

 

@Quentin Good set of additional tests, thank you!

  

 

 

 

Ksharp
Super User
Chris,
I like Tom's idea. Just take it as 'IN' operator in date step,
always put parentheses around the list of values , right ?

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
  • 6 replies
  • 1099 views
  • 5 likes
  • 5 in conversation