BookmarkSubscribeRSS Feed
Ronein
Meteorite | Level 14

Hello

Let's say that I define a parameter as following:

 

%let Vector=Reason1701 Reason1702 Reason1703 Reason1704 Reason1705 Reason1706
                    Reason1707 Reason1708 Reason1709 Reason1710 Reason1711 Reason1712
                    Reason1801 Reason1802 Reason1803 Reason1804 Reason1805;

 

I want to create a new parameter that will get value of number of arguments in parameter &vector.

I want that SAS will calculate number of arguments in  parameter &vector. (in this example:17 arguments)

Does anyone know how to do it?

Thanks

 

 

10 REPLIES 10
Kurt_Bremser
Super User

The countw function counts words in a string:

data _null_;
count = countw("&vector");
put count=;
run;

Since there is no %countw macro function, you have to use %sysfunc in a macro context:

%let count = %sysfunc(countw(&vector));
Ronein
Meteorite | Level 14

Thank you!

As I understand it is enough to write the code:

%let count= %sysfunc(countw(&vector));
%put &count.;

 

What is the purpose of  the code:

data _null_;
count = countw("&vector");
put count=;
run;

??

RW9
Diamond | Level 26 RW9
Diamond | Level 26

Its called a datastep.  Its part of Base SAS programing - this being the core of the SAS product and the actual product.  The syntax is a lot simpler, not having all the %&%&'s, and its a lot more robust.  Always use Base SAS programming, and only use Macro when its adds some value to the code.  Lists of data are best put into datasets - these are things designed to hold data.  This makes working with that data far simpler and more robust.

Ronein
Meteorite | Level 14

Hello

I need this new parameter (number of arguments) in order to create a flexible SAS program .

In this program user define only one parameter called  vector and  SAS create another parameter automatically(count parameter).

As I see I only use count as a parameter and don't use it in data step.

So actually I will only use code:

%let count= %sysfunc(countw(&vector));

Thank you so much  and I have learned a lot from this forum and i love SAS

 

 

 

 

RW9
Diamond | Level 26 RW9
Diamond | Level 26

So your not actually using that list of values?  If so why not just get the user to enter the number?  The reason why is your going to have to - to make any kind of robust programming - create a whole set of error checking on that macro variable.  What if the user enters:

xyy123,4 xyz124 ...

 

This will break your code.  If they enter too many your going to hit maximum line length.  There is a lot that can go wrong which you need to check for - needlessly if you not even using it.  Good planning, process planning is the way to do flexible programs.

Quentin
Super User

If your vector might sometimes have 0 elements, you will get an error:

 

1    %let Vector=;
2    %put >>%sysfunc(countw(&vector))<< ;
ERROR: The function COUNTW referenced by the %SYSFUNC or %QSYSFUNC macro function has too few
       arguments.
>>.<<

I suppose it's because %sysfunc has no argument to pass to COUNTW.  As I'm often in the situation where I want to allow a list to have 0 or more elements, I often specify the word delimiter for COUNTW.  That way there is always an argument, and it's happy to return 0. :

 

3    %put >>%sysfunc(countw(&vector,%str( )))<< ; *Space-delimited list;
>>0<<

 

 

The Boston Area SAS Users Group is hosting free webinars!
Next up: Joe Madden & Joseph Henry present Putting Power into the Hands of the Programmer with SAS Viya Workbench on Wednesday Nov 6.
Register now at https://www.basug.org/events.
Tom
Super User Tom
Super User

Adding the actual delimiter you want is useful since it can avoid wrong counts.

But to avoid the error when the macro variable is empty you just need to add ANYTHING.  So all of these will also work.

%put %sysfunc(countw(&x,));
%put %sysfunc(countw(%str()&x));
%put %sysfunc(countw(&x%str()));
%put %sysfunc(countw(%str(&x)));
%put %sysfunc(countw(%superq(x)));
Quentin
Super User

Actually %sysfunc(countw(&x,)) doesn't work.  I think it accepts a null value as the argument for the delimiter, so it returns 1 any time the first argument is not null, instead of using the default delimiters. 

 

1    %let x=hello world.how|are-you ;
2    %put >>%sysfunc(countw(&x,))<<;         *Null delimiter, returns 1 ;
>>1<<
3    %put >>%sysfunc(countw(&x,%str()))<< ;  *Null delimiter, returns 1 ;
>>1<<
4    %put >>%sysfunc(countw(&x,%str( )))<< ; *Blank delimiter, returns 2 ;
>>2<<
5    %put >>%sysfunc(countw(%str()&x))<<;    *Default delimiters, returns 5 ;
>>5<<
6    %put >>%sysfunc(countw(&x%str()))<<;    *Default delimiters, returns 5 ;
>>5<<
7    %put >>%sysfunc(countw(%str(&x)))<<;    *Default delimiters, returns 5 ;
>>5<<
8    %put >>%sysfunc(countw(%superq(x)))<<;  *Default delimiters, returns 5 ;
>>5<<

 

The Boston Area SAS Users Group is hosting free webinars!
Next up: Joe Madden & Joseph Henry present Putting Power into the Hands of the Programmer with SAS Viya Workbench on Wednesday Nov 6.
Register now at https://www.basug.org/events.
Kurt_Bremser
Super User

@Ronein wrote:

Thank you!

As I understand it is enough to write the code:

%let count= %sysfunc(countw(&vector));
%put &count.;

 

What is the purpose of  the code:

data _null_;
count = countw("&vector");
put count=;
run;

??


It's just there to show you how the countw() function works in its natural environment, which is the data step.

Kurt_Bremser
Super User

@Ronein wrote:

Thank you!

As I understand it is enough to write the code:

%let count= %sysfunc(countw(&vector));
%put &count.;

 

What is the purpose of  the code:

data _null_;
count = countw("&vector");
put count=;
run;

??


A PS here: as you can see from other posts, you need to take some precaution against the case where &vector is defined but empty if you do the count in macro. In the data step version, it simply does not matter. One of the reasons I like to do such manipulations/calculations/transforms in a data step with a final call symput:

data _null_;
count = countw("&vector");
/* if needed, add further processing here */
call symputx('count',put(count,best.));
run;

Data step programming simply does not have as many pitfalls.

SAS Innovate 2025: Save the Date

 SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!

Save the date!

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.

SAS Training: Just a Click Away

 Ready to level-up your skills? Choose your own adventure.

Browse our catalog!

Discussion stats
  • 10 replies
  • 1751 views
  • 7 likes
  • 5 in conversation