Him I would like to be able to pass a numeric range such as 2013:2017 into a macro and then iterate over it through it with a do loop.
It would look something like what I have below. I have wrote ....... where I am not sure of what to do.
%some_macro(year); %do ......... ; %let year_i = ............ ; %put year_I; %end; %mend some_macro;
I would like it to work with a range.
%some_macro(2013:2017);
But I also would like it to work with a single number.
%some_macro(2013);
Or with a list of numbers.
%some_macro(2013 2015 2018)
Not sure if this is possible or practical SAS, but i thought it would be interesting to try.
Thanks for the help.
-Bill
So you want to take space delimited list of values. Where each value is either a single number or a pair of numbers separated by a colon.
Scan the list. Then scan/parse the items in the list.
%macro some_macro(yearlist);
%local index token year;
%do index=1 %to %sysfunc(countw(&yearlist,%str( )));
%let token=%scan(&yearlist,&index,%str( ));
%do year=%scan(&token,1,:) %to %scan(&token,-1,:) ;
%put &=index &=token &=year ;
%end;
%put ;
%end;
%mend ;
%some_macro(2000 2010:2013 2015);
INDEX=1 TOKEN=2000 YEAR=2000 INDEX=2 TOKEN=2010:2013 YEAR=2010 INDEX=2 TOKEN=2010:2013 YEAR=2011 INDEX=2 TOKEN=2010:2013 YEAR=2012 INDEX=2 TOKEN=2010:2013 YEAR=2013 INDEX=3 TOKEN=2015 YEAR=2015
%macro dummy (parm= ); %do i=1 %to %sysfunc(countw(&parm)); %let value = %scan(&parm, &i); %put Value for &i. is &value.; %end; %mend; %dummy(parm= a b 234 q)
First thing to remember: MACRO VARIABLES ARE ALWAYS TEXT.
If you really want a "range" instead of an explicit list then use a separate parameter for the lower and upper bound (makes it clear what you are doing which could be masked by using one parameter with two values).
%macro dummy2 (lower= , upper= ); %do i=&lower. %to &upper. ; %put Value is &i.; %end; %mend; %dummy2(lower= 123, upper=127)
If you go this route I strongly suggest doing some error check coding to insure that lower is less than upper AND that the values are integers. Macro do loops aren't going to perform well with decimal values.
So you want to take space delimited list of values. Where each value is either a single number or a pair of numbers separated by a colon.
Scan the list. Then scan/parse the items in the list.
%macro some_macro(yearlist);
%local index token year;
%do index=1 %to %sysfunc(countw(&yearlist,%str( )));
%let token=%scan(&yearlist,&index,%str( ));
%do year=%scan(&token,1,:) %to %scan(&token,-1,:) ;
%put &=index &=token &=year ;
%end;
%put ;
%end;
%mend ;
%some_macro(2000 2010:2013 2015);
INDEX=1 TOKEN=2000 YEAR=2000 INDEX=2 TOKEN=2010:2013 YEAR=2010 INDEX=2 TOKEN=2010:2013 YEAR=2011 INDEX=2 TOKEN=2010:2013 YEAR=2012 INDEX=2 TOKEN=2010:2013 YEAR=2013 INDEX=3 TOKEN=2015 YEAR=2015
Are you ready for the spotlight? We're accepting content ideas for SAS Innovate 2025 to be held May 6-9 in Orlando, FL. The call is open until September 25. Read more here about why you should contribute and what is in it for you!
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.