BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
brophymj
Quartz | Level 8

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?

1 ACCEPTED SOLUTION

Accepted Solutions
MichaelPearce
Obsidian | Level 7

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

11 REPLIES 11
Jagadishkatam
Amethyst | Level 16

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
MichaelPearce
Obsidian | Level 7

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;

brophymj
Quartz | Level 8

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.);

MichaelPearce
Obsidian | Level 7

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;

brophymj
Quartz | Level 8


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?

MichaelPearce
Obsidian | Level 7

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;

brophymj
Quartz | Level 8

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?

MichaelPearce
Obsidian | Level 7

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

brophymj
Quartz | Level 8

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 ..."

MichaelPearce
Obsidian | Level 7

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;

RW9
Diamond | Level 26 RW9
Diamond | Level 26

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;

sas-innovate-2024.png

Join us for SAS Innovate April 16-19 at the Aria in Las Vegas. Bring the team and save big with our group pricing for a limited time only.

Pre-conference courses and tutorials are filling up fast and are always a sellout. Register today to reserve your seat.

 

Register now!

What is Bayesian Analysis?

Learn the difference between classical and Bayesian statistical approaches and see a few PROC examples to perform Bayesian analysis in this video.

Find more tutorials on the SAS Users YouTube channel.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

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