%sysevalf error when counting words with %sysfunc(findw())

Reply
New Contributor
Posts: 4

%sysevalf error when counting words with %sysfunc(findw())

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.

Super User
Posts: 23,667

Re: %sysevalf error when counting words with %sysfunc(findw())

%let columns = countn <figure> hazardratio hrlowercl hruppercl;
%let l_fign = %sysfunc(findw(&columns,<figure>,' ',ei));
%put [&l_fign];
Super User
Super User
Posts: 8,070

Re: %sysevalf error when counting words with %sysfunc(findw())

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.

 

New Contributor
Posts: 4

Re: %sysevalf error when counting words with %sysfunc(findw())

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!

PROC Star
Posts: 2,329

Re: %sysevalf error when counting words with %sysfunc(findw())

[ Edited ]

@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];

 

Ask a Question
Discussion stats
  • 4 replies
  • 148 views
  • 2 likes
  • 4 in conversation