How do I get EQ, NE etc... to not resolve to their 1 and 0 values in the Cats function?
See the log of my testing below.
35 %LET TEST1=%SYSFUNC(CATS(WordOne, WordTwo));
36 %PUT TEST1=&TEST1.;
TEST1=WordOneWordTwo
37
38 %LET TEST2=%SYSFUNC(CATS(WordOne,EQ,%STR(EQ),'NE'));
39 %PUT TEST2=&TEST2.;
TEST2=WordOne11'NE'
40
41 %LET TEST3=%SYSFUNC(CATS(WordOne,%BQUOTE(EQ),%BQUOTE(NE)));
42 %PUT TEST3=&TEST3.;
TEST3=WordOne10
43
44 %LET TEST4=%SYSFUNC(CATS(WordOne,GE));
45 %PUT TEST4=&TEST4.;
TEST4=WordOne1
46
47 %LET TEST5=%SYSFUNC(CATS(WordOne,GT));
48 %PUT TEST5=&TEST5.;
TEST5=WordOne0
49
50 %LET TEST6=%SYSFUNC(CATS(WordOne,%NRBQUOTE(EQ)));
51 %PUT TEST6=&TEST6.;
TEST6=WordOne1
52
53 %LET TEST7=%SYSFUNC(CATS(WordOne,"EQ"));
54 %PUT TEST7=&TEST7.;
TEST7=WordOne"EQ"
55
56 %LET TEST8=%SYSFUNC(CATS(WordOne,%QUOTE(EQ)));
57 %PUT TEST8=&TEST8.;
TEST8=WordOne1
58
59 %LET TEST9=%SYSFUNC(CATS(WordOne,%NRQUOTE(EQ)));
60 %PUT TEST9=&TEST9.;
TEST9=WordOne1
61
62 %LET TEST10=%SYSFUNC(CATS(WordOne,%NRSTR(EQ)));
63 %PUT TEST10=&TEST10.;
TEST10=WordOne1
That is because %eval( EQ ) is 1 and %eval( NE ) is 0. The CATS() function allows either numeric or character arguments, so %SYSFUNC() has to decide which one to tell it your call is providing. So that is why the boolean expression EQ is being evaluated as TRUE.
But why would you use CATS() function with %SYSFUNC()? To place strings next to each other in macro code just type them where you want them.
%LET TEST1=WordOneWordTwo;
%LET TEST2=WordOneEQ%str(EQ)'NE';
%LET TEST3=WordOne%BQUOTE(EQ)%BQUOTE(NE);
%LET TEST4=WordOneGE;
...
Because I am a dolt who likes to do things the most difficult way possible. 🙄
First, let's get rid of the CATS function. Macro language doesn't need it to concatenate text strings. You could simply code:
%let test1 = WordOne eq WordTwo;
If you would like this to resolve to a 0 or 1, surround it in %sysevalf:
%let test1 = %sysevalf(WordOne eq WordTwo);
However, note that you are comparing the text "WordOne" to the text "WordTwo". Macro language does not look at the value of variables within a data set.
Obviously, as others have stated, EQ and NE are evaluated to numeric values within CATS.
One way to avoid that: split them in pieces:
73 %LET TEST2=%SYSFUNC(CATS(WordOne,E,Q,E,Q,'NE'));
74 %put &=test2;
TEST2=WordOneEQEQ'NE'
@s_lassen wrote:
Obviously, as others have stated, EQ and NE are evaluated to numeric values within CATS.
One way to avoid that: split them in pieces:
73 %LET TEST2=%SYSFUNC(CATS(WordOne,E,Q,E,Q,'NE')); 74 %put &=test2; TEST2=WordOneEQEQ'NE'
That introduces a different concern. Depending on what letters you have included in the MISSING statement some single letter values will still be convert to numeric, resulting them coming out as uppercase.
632 missing e q ; 633 %LET TEST2=%SYSFUNC(CATS(WordOne,e,q,'NE')); 634 %put &=test2; TEST2=WordOneEQ'NE'
One more tiny pebble to add the the cairn of explanation you got so far.
%sysfunc must decide how to parse the code: is it macro code or is it text (that could be be passed to the sas language parser)? For EQ, it decides it's macro code.
I couldn't find a way to force the macro parser to see this as a simple string in this case.
SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!
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.