BookmarkSubscribeRSS Feed
pcohen
Calcite | Level 5

Hello,

I've stumbled upon some IF IN () syntax that works, but I cannot find any documentation as to why or how it works and I would like to learn more. I'm using SAS 9.4 on windows, here's my code and results:

 

*using the cars dataset from sashelp;
data cars; set sashelp.cars;
run;

*this is one of the normal ways I would create a flag for specific values in the variable MAKE;
data cars; set cars;
flag=make in ("Acura" "Mazda" "Toyota");
run;


*This is the new way that I found to make a flag for specific values in the variable MAKE;
*the best way I can describe it - placing the variable name as the first term creates an array;
*that the rest of the IN statement searches over for the remaining terms; data cars; set cars; flag2=0; if in (strip(make),"Acura","Mazda","Toyota") then flag2=1; run;
proc freq data=cars; table flag*flag2*make/list missing; run;

here are the results from the frequency:

sashelp.png

 

As you can see, flag2 correctly identified the same values as flag. This code seems to work, but I would like to be sure it will work in other situations by reviewing the documentation. Again, I have been searching online without any success.

 

Has anyone else used this syntax or found any documentation? Thank you!

6 REPLIES 6
ballardw
Super User

Interesting and apparently undocumented feature that a list of comma delimited character values will compare the first value to the remaining.

 

In this code:

data work.cars;
   set sashelp.cars;
   flag = in ( strip(make), "Acura","Mazda","Toyota" ) ;
   flag4= in (  "Acura","Mazda","Toyota",strip(make) ) ;
/*   flag2 = in ( strip(make) "Acura" "Mazda" "Toyota" ) ;*/
   flag3 = in ( cylinders, 4, 6);
run;

Flag behaves as your example. Flag4 gets set to 1 only when Make is Acura. Flag2, if uncommented, creates an error about expected operator or function

1746     flag2 = in ( strip(make) "Acura" "Mazda" "Toyota" ) ;
                                  -------
                                  22
                                  200
ERROR 22-322: Syntax error, expecting one of the following: !, !!, &, ), *, **, +, ',', -, /, <,
              <=, <>, =, >, ><, >=, AND, EQ, GE, GT, IN, LE, LT, MAX, MIN, NE, NG, NL, NOT,
              NOTIN, OR, ^, ^=, |, ||, ~, ~=.

ERROR 200-322: The symbol is not recognized and will be ignored.

and Flag4 generates

NOTE: Numeric values have been converted to character values at the places given by:
      (Line):(Column).

referencing the positions of Cylinders, the 4 and the 6 and the flag is set to one when matching.

 

I am wondering if we are getting a side effect of the in operator requires a single value before the IN and all the values get pushed into a stack. So when no value precedes the operator the first element of the stack is missing but the compiler evaluates the remaining items. But the character only is interesting.

pcohen
Calcite | Level 5

Thanks for looking into this! What you've explained makes sense - the comma delimited character values compare the first value to the remaining. You can also list multiple variables instead of one variable and multiple values and get the same outcome.

Unless there are other uses for this feature, I do not see how it will be any more useful than other features as it is more challenging to use. I found that if I did not strip the variable within the statement, it was unable to locate values of shorter lengths, but if I added trailing blanks to the values it would work. Very strange feature.

pcohen
Calcite | Level 5

Thanks for replying. To be clear, the first flag is not the one I am asking about, it's the second one (flag2).

 

As it shows in the documentation you provided, the syntax is that the variable needs to be placed after the "if" and before the "in":

if state in ('NY','NJ','PA')

 

For whatever reason, that is not always the case and the variable can be placed inside the parenthesis while still producing the same results. I'm trying to understand why this code works:

if in (strip(state),'NY','NJ','PA') 

andreas_lds
Jade | Level 19

The second usage of "in" indicates, that a function named "in" exists, returning the very same result as the in-operator.

Kurt_Bremser
Super User

This looks like an undocumented function. Bring this to the attention of SAS Technical Support, so that the documentation is updated.

 

While the in operator automatically strips the argument to the left, the function needs the "manual" strip.

Ready to join fellow brilliant minds for the SAS Hackathon?

Build your skills. Make connections. Enjoy creative freedom. Maybe change the world. Registration is now open through August 30th. Visit the SAS Hackathon homepage.

Register today!
Mastering the WHERE Clause in PROC SQL

SAS' Charu Shankar shares her PROC SQL expertise by showing you how to master the WHERE clause using real winter weather data.

Find more tutorials on the SAS Users YouTube channel.

Discussion stats
  • 6 replies
  • 502 views
  • 1 like
  • 5 in conversation