Hi all,
I have the following code, but am not getting the desired result. It works only with one condition but not other. Please let me know how to fix this
%macro test(dsn=,var=);
data &dsn;
set core(where=(cat="&var"));
run;
%if &var eq CL %then %do;
proc print data=&dsn;
run;
%end;
%else %do;
proc contents data=&dsn;
run;
%end;
%mend;
Macro call :
%test(dsn=dsn1,var=CL); This one is working
%test(dsn=dsn1,var=CL-VT-MO);
Log shows the following error;
A character operand was found in the %EVAL function or %IF condition where a numeric operand is required.
The condition was: &cond eq CL
Appreciate your input
Thanks
The SAS macro processor interprets the dash as subtraction, which doesn't make sense in this situation. So, you need to tell the SAS macro processor not to do that.
%test(dsn=dsn1,var=%str(CL-VT-MO))
The SAS macro processor interprets the dash as subtraction, which doesn't make sense in this situation. So, you need to tell the SAS macro processor not to do that.
%test(dsn=dsn1,var=%str(CL-VT-MO))
In a %IF condition, simple arithmetic can be used (in this, the macro processor deviates from being a "pure text" processor). That's why you need to "mask" arithmetic operators.
Hi @sri1 This is a very interesting question that stumped me a few years ago. Basically, what we need to understand is that how a macro %IF %THEN %ELSE treats INTEGER arithmetic and FLOAT arithmetic.
The default behavior of a %IF is to compute INTEGER arithmetic/comparison operators. Therefore when the macro processor "tokenises" the code syntax bits that had operators that are of the arithmetic/comparison operator, it evaluates the component by sending signals to the ALU(arithmetic logical unit), places back the result and then continues to process the next subsequent tokens.
However, the same %IF is not designed to compute/evaluate FLOAT arithmetic by default and would often result in a similar error that you encountered. Moreover, in your case, the macro processor sees CL, VT and MO as character constant operands and so there is no way that it can compute or evaluate an INTEGER-arithmetic operation.
This leads to the situation in us finding a way to treat the operators as text, so that the default behavior of macro processor when dealing with tokens within a %IF is changed to processing regular name tokens aka text.
The macro quoting functions, like %STR,%BQUOTE does just that. Of course there is a difference between how stuff works %STR vs%BQUOTE besides the fact former works at compile time and the latter works at execution time with some nuances, but that's beyond the scope of this question in my opinion.
So the following should fix-
%test(dsn=dsn1,var=%str(CL-VT-MO))
/*OR*/
%test(dsn=dsn1,var=%bquote(CL-VT-MO))
Hope that helps.
PS Thank you @mkeintz and @Tom for helping me understand this. I guess you both were young back then. 🙂 lol
The problem is this statement:
%if &var eq CL %then %do;
And the solution is shown in the step just above.
data &dsn;
set core(where=(cat="&var"));
run;
Just change your test to:
%if "&var" eq "CL" %then %do;
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!
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.