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<<

 

 

BASUG is hosting free webinars Next up: Jane Eslinger presenting PROC REPORT and the ODS EXCEL destination on Mar 27 at noon ET. Register now at the Boston Area SAS Users Group event page: 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<<

 

BASUG is hosting free webinars Next up: Jane Eslinger presenting PROC REPORT and the ODS EXCEL destination on Mar 27 at noon ET. Register now at the Boston Area SAS Users Group event page: 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-2024.png

Join us for SAS Innovate April 16-19 at the Aria in Las Vegas. Bring the team and save big with our group pricing for a limited time only.

Pre-conference courses and tutorials are filling up fast and are always a sellout. Register today to reserve your seat.

 

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
  • 10 replies
  • 1139 views
  • 7 likes
  • 5 in conversation