From SAS documentation at: SAS(R) 9.2 Macro Language: Reference
The following is an example using a specified delimiter in an IN operator:
%put %eval(a in d,e,f,a,b,c); /* should print 0 */
%put %eval(a in d e f a b c); /* should print 1 */
option mindelimiter=',';
%put %eval(a in d,e,f,a,b,c); /* should print 1 */
%put %eval(a in d e f a b c); /* should print 0 */
Great, so I copy and paste the code above into a brand new SAS 9.3 (not SAS 9.2, because I no longer have SAS 9.2) session, and here is the SASLOG
1 | %put %eval(a in d,e,f,a,b,c); /* should print 0 */ |
ERROR: A character operand was found in the %EVAL function or %IF condition where a numeric operand is required. The condition
was: a in d,e,f,a,b,c |
2 | %put %eval(a in d e f a b c); /* should print 1 */ |
ERROR: A character operand was found in the %EVAL function or %IF condition where a numeric operand is required. The condition
was: a in d e f a b c |
3 | option mindelimiter=','; |
4 | %put %eval(a in d,e,f,a,b,c); /* should print 1 */ |
ERROR: A character operand was found in the %EVAL function or %IF condition where a numeric operand is required. The condition
was: a in d,e,f,a,b,c |
5 | %put %eval(a in d e f a b c); /* should print 0 */ |
ERROR: A character operand was found in the %EVAL function or %IF condition where a numeric operand is required. The condition
was: a in d e f a b c |
I hope someone can explain why this isn't working. Thanks.
Paige,
There is a second related option, MINOPERATOR vs. NOMINOPERATOR. Make sure you're using the former, not the latter.
Good luck.
You probably do not have the MINOPERATOR option set.
%put %sysfunc(getoption(MINOPERATOR));
Message was edited by: FriedEgg Nice work Astounding, beat me to the post.
Thanks, @Astounding and @FriedEgg. That was the issue.
Isn't it interesting how the SAS documentation never mentioned the MINOPERATOR option at all? It simply implied that the code would work, and it didn't work.
They have it in the SEE ALSO section, if that is in any way meaningful. It could definitely be made more pronounced as being necessary...
SAS(R) 9.3 Macro Language: Reference
The documentation for MINOPERATOR covers the relationship between the two options better:
Is there any reason to NOT turn on MINOPERATOR globally?
For consideration:
1. When IN was first made available to macro language, it really wasn't ready. It was extremely buggy in the first release.
2. In macro language, # can be a substitute for IN. Could some programmers have used # intending it to have other meaning? Would that cause a problem?
The only time I can ever remember using a # in SAS is in PROC IML.
But since its easy enough to turn these options on for specific macros, or specific sections of code, I'll do that.
The usage probably doesn't have to be that obscure. This is a bit of a stretch, but I wouldn't want to predict what would happen:
%if &saying = come in to my parlor %then %do;
Ouch! I ran the following test:
%macro macro1;
%let saying=come in to my parlor;
%if &saying. eq come in to my parlor %then %do;
%put xxx1;
%end;
%mend;
%macro macro2 / mindelimiter=',';
%let saying=come in to my parlor;
%if &saying. eq come in to my parlor %then %do;
%put xxx3;
%end;
%mend;
option minoperator;
%macro1
%macro2
option nominoperator;
%macro1
%macro2
If you're saying that this is a bug (a pretty serious bug, IMHO), then you should definitely submit a report to SAS.
Or, are you saying the program is operating correctly, but not in ways you want it to operate?
If I'm going to make use of this feature in SAS, I need to understand why your macro code performs the way it does, and right now I don't understand. Looks like a serious bug to me.
Can you explain why it performs the way it does?
Art,
I don't think I can start my own tests until Monday. But here is one piece I would add:
%if away in a manger = come in to my parlor %then %do;
I suspect that %EVAL will get invoked automatically as part of an %IF condition (but I haven't seen results from your tests yet).
: I really don't have much time to test or explain it right now. The original test only worked if the nominoperator option was in effect.
I don't think %eval is automatically invoked or at least I wasn't able to come up with a working example without it.
Paige, I think the following example might explain why I don't think it is necessarily a bug:
%let saying=1;
%macro macro1;
%if &saying eq %eval(my in to,my,parlor) %then %do;
%put xxx1;
%end;
%mend;
%macro macro2 / mindelimiter=',';
%if &saying eq %eval(my in to,my,parlor) %then %do;
%put xxx2;
%end;
%mend;
option minoperator;
%macro1
%macro2
option nominoperator;
%macro1
%macro2
Join us for SAS Innovate 2025, our biggest and most exciting global event of the year, in Orlando, FL, from May 6-9. Sign up by March 14 for just $795.
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.
Ready to level-up your skills? Choose your own adventure.