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
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));
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;
??
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.
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
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.
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<<
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)));
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<<
@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.
@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 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!
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.
Ready to level-up your skills? Choose your own adventure.