BookmarkSubscribeRSS Feed
☑ This topic is solved. Need further help from the community? Please sign in and ask a new question.
Quentin
Super User

That shown style of looping over a list with %DO %UNTIL was common prior to the introduction of the COUNTW function.  I think COUNTW was introduced in v7 or v8. 

 

I would agree that using COUNTW to count the number of items in a list seems clearer to me also.

quickbluefish
Barite | Level 11

Agree with others here - I would just add that with COUNTW and SCAN (and similar), it's a good idea to specify your delimiter as the optional last argument - otherwise, SAS will try to guess.  And further, if the delimiter is a space (as it is here), never a bad idea to clean up potential multiple whitespace characters with %CMPRES:


%let YRLIST=2012 2014 2016;
%let YRLIST=%CMPRES(&YRLIST);
%let nYRS=%sysfunc(countW(&YRLIST,' '));

.... %let YR=%SCAN(&YRLIST, &i, ' ');

* you can also use %STR( ) instead of ' ' above ;

 

dxiao2017
Lapis Lazuli | Level 10

Thanks a lot for your comments! I tested your examples and somehow got something like this (see below). I have three questions: 1) it looks like the %cmpres function is not necessary (at least in my example), if I run the %cmpres statement I got error message; 2) if I want to clean up whitespace characters the function to be use is compbl (I do not know how this function is written when it is a macro function), not compress, am I right or wrong? 3) this question is not relevant, how can I make the code posted here colored?

(after I post THIS message I found it is colored somehow, however, the code in my previous post were not)

%let yrlist=%nrstr(2010 % 2012 2014,2016   2018 & 2019);
*%let yrlist=%cmpres(&yrlist,'%,&');
*%put &yrlist;
%let nyrs=%sysfunc(countw(&yrlist,' %,&'));
%put &nyrs;

dxiao2017_0-1741138251243.png

 

Quentin
Super User

@quickbluefish wrote:

Agree with others here - I would just add that with COUNTW and SCAN (and similar), it's a good idea to specify your delimiter as the optional last argument - otherwise, SAS will try to guess.  And further, if the delimiter is a space (as it is here), never a bad idea to clean up potential multiple whitespace characters with %CMPRES:


%let YRLIST=2012 2014 2016;
%let YRLIST=%CMPRES(&YRLIST);
%let nYRS=%sysfunc(countW(&YRLIST,' '));

.... %let YR=%SCAN(&YRLIST, &i, ' ');

* you can also use %STR( ) instead of ' ' above ;

 


I agree it's good practice to specify the delimiter for COUNTW and %SCAN.  Particularly because if you have an empty list, %sysfunc(countw()) will throw an error, but %sysfunc(countw(,%str( )))  will return 0.

 

That said, I think it's much clearer/better to use %STR( ) to specify the blank as delimiter, rather than ' '.  If you use ' ' you're telling the macro processor to use both blank and a single quote as delimiters.  In the macro language ' ' is a three character string, not a single blank.

dxiao2017
Lapis Lazuli | Level 10
PS: the countw() function and the code I took as reference is on page37, page41 of SAS Programming3: Advanced Techniques course notes PDF.

sas-innovate-2026-white.png



April 27 – 30 | Gaylord Texan | Grapevine, Texas

Registration is open

Walk in ready to learn. Walk out ready to deliver. This is the data and AI conference you can't afford to miss.
Register now and lock in 2025 pricing—just $495!

Register now

Autotuning Deep Learning Models Using SAS

Follow along as SAS’ Robert Blanchard explains three aspects of autotuning in a deep learning context: globalized search, localized search and an in parallel method using SAS.

Find more tutorials on the SAS Users YouTube channel.

Discussion stats
  • 35 replies
  • 9225 views
  • 22 likes
  • 5 in conversation