Help using Base SAS procedures

Macro variables within loop

Accepted Solution Solved
Reply
Super Contributor
Posts: 259
Accepted Solution

Macro variables within loop

I define a macro variable at the top of my sas program as %let enddate = 20130328; and I want to reference it in a loop later on in the program within a datastep.

I have a loop that runs from year 2008 to 2013 and months 1 to 12 but i want the loop to cutoff at month 3 for year 2013; I was going allong this lines:

%Do y = 2008 %to 2013;

If &Y = 2013 then X = month(&enddate) ;

else X = 12;

%do M = 1 %to X;

The program works perfectly when I hawve %do M = 1 %to 12;

Any ideas?


Accepted Solutions
Solution
‎08-19-2014 07:41 AM
Occasional Contributor
Posts: 18

Re: Macro variables within loop

Ah that is easy, while SAS will not assume 20130328 is a date, it can convert it from anything to anything.

%macro thing;
   %let enddate=20130328;
   %let endDt=%sysfunc(inputn(&enddate,yymmdd8.));

   %do y= 2008 %to 2013;
      %if &Y = 2013 %then
          %let X = %sysfunc(month(&enddt));
      %else
          %let X = 12;

      %do M = 1 %to &X;
         %put y=&y m=&m;
      %end;
   %end;
%mend;

%thing;

View solution in original post


All Replies
Trusted Advisor
Posts: 1,131

Re: Macro variables within loop

could it is possible to run the loop for 2013 upto 12 months and then subset the data where date is less than month 3 and year 2013.

Thanks,

Jag

Thanks,
Jag
Occasional Contributor
Posts: 18

Re: Macro variables within loop

The problems come from SAS not knowing 20130328 is a date.

With pure macro code you could do this.

%macro thing;
   %let enddate="28MAR2013"d;

   %do y= 2008 %to 2013;
      %if &Y = 2013 %then
          %let X = %sysfunc(month(&enddate));
      %else
          %let X = 12;

      %do M = 1 %to &X;
         %put y=&y m=&m;
      %end;
   %end;
%mend;

%thing;

Super Contributor
Posts: 259

Re: Macro variables within loop

Thanks Michael, this is perfect but I need someway of converting 20130328 to a sas date. The program defines the date as an 8 digit number at the start (and unfortuantely I can't change this) but is there a way to change this in your code above, like %let date = input(substr(&enddate,1,6), best.);

Solution
‎08-19-2014 07:41 AM
Occasional Contributor
Posts: 18

Re: Macro variables within loop

Ah that is easy, while SAS will not assume 20130328 is a date, it can convert it from anything to anything.

%macro thing;
   %let enddate=20130328;
   %let endDt=%sysfunc(inputn(&enddate,yymmdd8.));

   %do y= 2008 %to 2013;
      %if &Y = 2013 %then
          %let X = %sysfunc(month(&enddt));
      %else
          %let X = 12;

      %do M = 1 %to &X;
         %put y=&y m=&m;
      %end;
   %end;
%mend;

%thing;

Super Contributor
Posts: 259

Re: Macro variables within loop


Thanks Michael, when i reference enddt outside a data step i get an error saying "argument 1 to function year referenced by the sysfunc macro function is not a number"

Do you have to do somthing different when it's outside the data step?

Occasional Contributor
Posts: 18

Re: Macro variables within loop

Well none of that is in a data step, it's all macro, if you want it all to run in a data step, it gets easier to read ...

%let enddate=20130328;

data _null_;
  endDt = input("&enddate",yymmdd8.);

  do y= 2008 to 2013;
    if Y = 2013 then
       X = month(enddt);
    else
       X = 12;

    do M = 1 to X;
      put y= m=;
    end;
  end;
run;

Super Contributor
Posts: 259

Re: Macro variables within loop

The enddate variable is defined outside the macro at the start of the whole program - you're code above works perfectly when i use it within a large datastep - i think i need to use your code since the macro variable &enddate was defined outside the datastep.

I'm still not sure why I'm getting the error message above?

Occasional Contributor
Posts: 18

Re: Macro variables within loop

It's probably the quotes, in a data step, they are needed, in macro code they are not.

Super Contributor
Posts: 259

Re: Macro variables within loop

To put it a different way, suppose I want to create a macro variable (without any other code involved) called year 1. The code %let year1 = %sysfunc(year("13JUL2013"d)); gives me the same error, that is:

"Argument 1 to function YEAR referenced by ..."

Occasional Contributor
Posts: 18

Re: Macro variables within loop

Are you mixing macro code and data step variables?

Because when i run:

%let year1 = %sysfunc(year("13JUL2013"d));

It works .. Log:

424  %let year1 = %sysfunc(year("13JUL2013"d));

425  %put Year One=&year1;

Year One=2013

If you want to create a macro variable from a field in your data step, you need to use call symput(), not %let.

data _null_;
  dt = date();
  put dt=date9.;

  call symput('YearOne',year(dt));
run;

%put Year One=&yearOne;

Super User
Super User
Posts: 7,413

Re: Macro variables within loop

Something like the below, just a matter of setting your loops up and having a conditional within, you could also do this with a do until, do while, or even if your really enjoying it, a do loop with months as your step value.

%let date=20130328;

data _null_;

     do I=2008 to input(substr(&date.,1,4),best.);

          do I=to 12;

               if input(substr(&date.,1,4),best.) < I or (input(substr(&date.,1,4),best.)=I and input(substr(&date.,5,2),best.) <= I then

                    YM=put(I,4.)||"-"||put(d,z2.);

               end;

          end;

     end;

run;

☑ This topic is solved.

Need further help from the community? Please ask a new question.

Discussion stats
  • 11 replies
  • 349 views
  • 0 likes
  • 4 in conversation