BookmarkSubscribeRSS Feed
rhale
Fluorite | Level 6

Can somebody please say what the problem is with this piece of code:

 

%let columns = countn <figure> hazardratio hrlowercl hruppercl;
%let l_fign = %sysfunc(findw(&columns,<figure>,%str( ),ei));
%put [&l_fign];

The problem seems to lie with the space delimiter %str( ). It gives the right "answer" [2] but it also gives this error:

 

ERROR: %SYSEVALF function has no expression to evaluate.

(Interestingly, with this error present, some sql code further down in my macro simply fails to run, although it mprint-s.)

 

If the values in COLUMNS are, say, $-delimited, the problem goes away:

%let l_fign = %sysfunc(findw(%sysfunc(prxchange(s/\s+/\$/,-1,&columns)),<figure>,$,ei));
%put [&l_fign];

An explanation would be greatly appreciated, as would a suggestion as to how to get the code to run error-free with a space delimiter. I'm using SAS 9.4M3 on Linux X64.

4 REPLIES 4
Reeza
Super User
%let columns = countn <figure> hazardratio hrlowercl hruppercl;
%let l_fign = %sysfunc(findw(&columns,<figure>,' ',ei));
%put [&l_fign];
Tom
Super User Tom
Super User

The problem is that for functions like FINDW() that interpret the meaning of the parameters passed based on their type.  In macro code everything is a string.  So the %SYSFUNC() macro function tries to test whether the string being passed should be considered character or numeric.  It is that detection phase that is generating the error message.  It works when you use $ since then %SYSFUNC() has a easier time determining the type.

 

@Reeza 's solution works because adding the single quote character to the list of delimiters also makes it easy for %SYSFUNC() to determine the type.  But it will change the result if the string being searched includes single quote characters.

 

Changing the delimiter in the way you have should eliminate the issue.  You might want to use TRANSLATE() instead just in case the input string already has the $ character.

 

Try this example.

%let columns = co$<figure>$untn hazardratio <figure> hrlowercl hruppercl;
%let l_fign = %sysfunc(findw(&columns,<figure>,%str( ),ei));
%put [&l_fign];

%let l_fign = %sysfunc(findw(%sysfunc(prxchange(s/\s+/\$/,-1,&columns)),<figure>,$,ei));
%put [&l_fign];

%let l_fign = %sysfunc(findw(%qsysfunc(translate(&columns,%str( $),%str($ ))),<figure>,$,ei));
%put [&l_fign];

You will see that the version with the prxchange() function call finds the wrong location.

 

rhale
Fluorite | Level 6

Ah, thank you Reeza and Tom, that's very interesting. I think I can safely go with Reeza's solution because COLUMNS will always contain a pre-validated list of variable names plus <figure> somewhere in the list. Thanks again!

ChrisNZ
Tourmaline | Level 20

@Reeza's answer could lead to thinking that empty strings are recognised by the macro language when   '  '   is encountered.

 

To remove any confusion, I'd rather add another delimiter like this:

 

%let columns = countn <figure> hazardratio hrlowercl hruppercl;
%let l_fign = %sysfunc(findw(&columns,<figure>,%str(~ ),ei));
%put [&l_fign];

 

Note that the following should remove any confusion for the macro parser as to what is where, but still generates the message somehow. Possibly a defect:

%let columns = countn <figure> hazardratio hrlowercl hruppercl;
%let l_fign = %sysfunc(findw(&columns,<figure>,1,%str( ),ei));
%put [&l_fign];

 

sas-innovate-2024.png

Don't miss out on SAS Innovate - Register now for the FREE Livestream!

Can't make it to Vegas? No problem! Watch our general sessions LIVE or on-demand starting April 17th. Hear from SAS execs, best-selling author Adam Grant, Hot Ones host Sean Evans, top tech journalist Kara Swisher, AI expert Cassie Kozyrkov, and the mind-blowing dance crew iLuminate! Plus, get access to over 20 breakout sessions.

 

Register now!

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.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

Discussion stats
  • 4 replies
  • 6833 views
  • 3 likes
  • 4 in conversation