Help using Base SAS procedures

%do loop - when parameter values not consecutive

Reply
Frequent Contributor
Posts: 107

%do loop - when parameter values not consecutive

Hi,

I'd like to use %do year=2002  %to year=2011 for the 10 years of data I'd like to run, however, my source data is not 4 digits or even 2 digits, but like 0203, 0304, 0405 ...1112. How can I get around with it if I still want to use %do loop?

>>>> If I don't use %do %to:

proc means data=amount0203 nway noprint;

     var amount; class sex;

     output out=out2002 (drop=_type_ _freq_) sum=;

     run;

...

proc means data=amount1112 nway noprint;

     var amount; class sex;

     output out=out2011 (drop=_type_ _freq_) sum=;

     run;

I was hoping to use %do YEAR=2001 %to 2011, but how do I get around with the nonconsecutive part of the dataset name while using %do loop?

%macro year();

%do YEAR=2002 %to 2011;

proc means data=amount***1112*** nway noprint;

     var amount; class sex;

     output out=out&YEAR (drop=_type_ _freq_) sum=;

     run;

%end;

%mend year;

%year;

Thanks in advance.

Super User
Posts: 11,343

Re: %do loop - when parameter values not consecutive

Try this instead of year use the last 2 digits. Since macro do loops currently don't do non-integer values...

 

%do i = 2 %to 11;

   %let first = %sysfunc(putn(&i,z2.));

   %let second= %sysfunc(putn(%eval(&i+1),z2.));

   %let ystr= &first.&second;

/* put your analysis here using &ystr in your amount data sets*/

/* and output = out20&i */

%end;

WARNING: Solution only valid for years 2000 to 2098.

Frequent Contributor
Posts: 107

Re: %do loop - when parameter values not consecutive

Thanks a lot. It is a really neat way of doing it. Much appreciated for the code.

Super User
Super User
Posts: 7,042

Re: %do loop - when parameter values not consecutive

Note that you do no normally need %EVAL() to evaluate simple arithmetic inside of %SYSFUNC() parameter values.  The function evaluation will do that.

To handle century cross-overs use Z4. format and take the last two digits.

%macro xx(s,e);

  %do i = &s %to &e;

    %let ds=%substr(%sysfunc(putn(&i,z4.)),3)%substr(%sysfunc(putn(&i+1,z4.)),3);

    %put i=&i ds=&ds;

  %end;

%mend;

175  %xx(8,11);

i=8 ds=0809

i=9 ds=0910

i=10 ds=1011

i=11 ds=1112


176  %xx(1998,2002);

i=1998 ds=9899

i=1999 ds=9900

i=2000 ds=0001

i=2001 ds=0102

i=2002 ds=0203

Super User
Posts: 10,028

Re: %do loop - when parameter values not consecutive

Or Call execute() function.

data amount0203;set sashelp.class;amount=1;run;
data amount1112;set sashelp.class;amount=2;run;

data _null_;
 set sashelp.vmember(keep=memname libname where=(libname='WORK' and memname like 'AMOUNT%'));
 call execute('proc means data='||strip(memname)||' nway noprint;var amount; class sex; output out=out20'||substr(memname,7,2)||' (drop=_type_ _freq_) sum=;run;');
run;

Ksharp

Super Contributor
Posts: 387

Re: %do loop - when parameter values not consecutive

Yet another approach, which works with any list of delimited tokens:

%macro debug;

  %put %scan(&word,1,|);

  %put %scan(&word,2,|);

  %put;

%mend;

%macro means;

  proc means data=amount%scan(&word,1,|) nway noprint;

    var amount; class sex;

    output out=out%scan(&word,2,|) (drop=_type_ _freq_) sum=;

  run;

%mend;

%macro build_list;

  %global list;

  %do i=2 %to 12;

    %let j=%eval(&i+1);

    %if (%superq(list) eq ) %then

      %let list=%sysfunc(putn(&i,z2.))%sysfunc(putn(&j,z2))|20%sysfunc(putn(&i,z2.));

    %else

      %let list=&list ^ %sysfunc(putn(&i,z2.))%sysfunc(putn(&j,z2))|20%sysfunc(putn(&i,z2.));

  %end;

%mend;

%let list=;

%build_list;

%put &list;

* alternative, non-macro approach ;

%let list=;

data _null_;

  length list $1000;

  do i=2 to 12;

list=catx(" ^ ",list,cats(put(i,z2.),put(i+1,z2.),"|","20",put(i,z2.)));

  end;

  call symputx("list",list);

run;

%put &list;

* test ;

%loop(&list,dlm=^,mname=debug);

* run ;

%loop(&list,dlm=^,mname=means);

See attached loop macro...

HTH,

Scott

Attachment
Ask a Question
Discussion stats
  • 5 replies
  • 737 views
  • 0 likes
  • 5 in conversation