DATA Step, Macro, Functions and more

Applying countw to an empty string

Accepted Solution Solved
Reply
Contributor
Posts: 24
Accepted Solution

Applying countw to an empty string

Hello.

I have been trying to make a macro function that counts the number of words in a given string. I use the function countw, but it seems it doesn't work correctly when applied to an empty string. My program is as follows.

%let words = ;

%macro no_of_words;

     %if &words = " " %then %do;

          amount = 0;

     %end;

     %else %do;

          amount = %sysfunc(nwords(&words));

     %end;

%mend;

data how_many;

%no_of_words´;

put amount;

run;

The error message from the log is "The function COUNTW referenced by the %SYSFUNC or %QSYSFUNC macro function has too few arguments."

The program works, if words contains a non-empty string. Any idea as to what my problem is, and how to avoid it?

Kind regards.


Accepted Solutions
Solution
‎02-27-2012 11:14 AM
PROC Star
Posts: 7,364

Applying countw to an empty string

You have a couple of problems, beside the code you posted not being that which you ran.  Does the following do what you want?

%let words = this is;

%macro no_of_words;

     %if &words = /*" "*/ %then %do;

          amount = 0;

     %end;

     %else %do;

          amount = %sysfunc(countw(&words));

     %end;

%mend;

data how_many;

%no_of_words

put amount;

run;

View solution in original post


All Replies
Solution
‎02-27-2012 11:14 AM
PROC Star
Posts: 7,364

Applying countw to an empty string

You have a couple of problems, beside the code you posted not being that which you ran.  Does the following do what you want?

%let words = this is;

%macro no_of_words;

     %if &words = /*" "*/ %then %do;

          amount = 0;

     %end;

     %else %do;

          amount = %sysfunc(countw(&words));

     %end;

%mend;

data how_many;

%no_of_words

put amount;

run;

Super User
Posts: 5,093

Applying countw to an empty string

Hedegaard,

The fault lies in your first comparison:

%if &words = " " %then %do;

Macro language does not require quotes.  This statement actually compares &WORDS to a set of 3 characters:  a double quote, followed by a space, followed by another double quote.

This replacement would be acceptable:

%if &words = %then %do;

But this would be safer:

%if %length(&words)=0 %then %do;

There are some text strings that could appear within &WORDS that would cause trouble in the %IF comparison.  This is one method to avoid that trouble.

Super User
Posts: 10,538

Re: Applying countw to an empty string

This is the one I use:

%MACRO WORDS(STRING);

%sysfunc(countw(&string,' ,')) /*does this in 9.1 NOTE there is no ; if included it is returned as part of the value*/

%MEND;

Requires SAS 9.1 or later.

Returns 0 for an empty string. You could modify the delimiter list.

The "need" for this existed for me as I had a prior version dating back to SAS 6 from before the %sysfunc statement.

Contributor
Posts: 24

Re: Applying countw to an empty string

Thank you all.

art297: Yes, that is what I meant to write - sorry I got it mixed up.

Astounding: I now use

%if %length(&words)=0 %then %do

instead,

and it seems to work just fine. Smiley Happy

Super User
Posts: 5,093

Re: Applying countw to an empty string

Hedegaard,

See if this makes sense to you as a next step.  Your macro would be much more widely applicable if it did NOT generate amount=, but merely generated the number.  For example:

%macro no_of_words (words);

   %if %length(&words)=0 %then 0;

   %else %sysfunc(countw(&words, %str( )));

%mend no_of_words;

That last piece with a blank inside the parentheses -- %str( ) -- is the right way to use only blanks as delimiters.  You would use the macro wherever you want the number to appear.  For example:

data how_many;

amount = %no_of_words(&words);

put amount;

run;

It looks strange the first time you see it, but it's very practical and effective.

☑ This topic is solved.

Need further help from the community? Please ask a new question.

Discussion stats
  • 5 replies
  • 683 views
  • 6 likes
  • 4 in conversation