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

Hi Everyone,

I want to run a process every 3 month from 1990-2013.

I setup my macro like that:

%macro Myproblem (m=,y=);

data period; set original_data:

    

     if m-3<month<=m+3 and year=y;

...

....

%mend;

%myproblem (m=3,y=1990);

%myproblem (m=6,y=1990);

...

...

%myproblem (m=12,y=2014);

Sure this code run but I believe that there should be a more efficient way rather than listing all (m=,y=).

Could you suggest a better way in this case?

(I know another way that make 02 files, 1 is the marco itself ; and 1 is for the m and y running together with calling the macro file.)

Thank you so much.

HHC

1 ACCEPTED SOLUTION

Accepted Solutions
slchen
Lapis Lazuli | Level 10

Use sashelp.workers as example.

%macro test (start,end);

    %do i=&start %to &end;

    %do j=3 %to 12 %by 3;

          data year_&j.&i;

      set sashelp.workers;

      if month(date)=&j and year(date)=&i then output;

  run;

   %end;

   %end;

%mend test;

%test (1977,1980);

View solution in original post

6 REPLIES 6
Tom
Super User Tom
Super User

Why not just convert the date in your source file into a quarter and use BY group processing?

data period ;

set original_data ;

qtr = put(datevar,YYQTR6.);

run;

proc means;

by qtr ;

run;

Otherwise loop by quarter.

%macro loop(start,end);

  %do i=0 %to %sysfunc(intck(qtr,&start,&end)) ;

     %let qtr=%sysfunc(intnx(qtr,&start,&i),yyq6) ;

     %put start=&start i=&i qtr=&qtr end=&end ;

     proc print data=original ;

       where put(date,yyq6.) = "&qtr" ;

       title "Data for Quarter &qtr" ;

     run;

  %end;

%mend loop;

data original ;

  do date='01FEB1990'd to '10APR1991'd by 90 ;

    output;

  end;

  format date date9.;

run;

%loop('01JAN1990'd,'31DEC1991'd);

slchen
Lapis Lazuli | Level 10

Use sashelp.workers as example.

%macro test (start,end);

    %do i=&start %to &end;

    %do j=3 %to 12 %by 3;

          data year_&j.&i;

      set sashelp.workers;

      if month(date)=&j and year(date)=&i then output;

  run;

   %end;

   %end;

%mend test;

%test (1977,1980);

hhchenfx
Rhodochrosite | Level 12

Good morning,

Thank you for your help.

Since the data is quite large and the processing is heavy, I think about split the whole sample in to pieces to deal with one by one.

Have a nice day.

HHC

Ksharp
Super User

Are you trying to split table ?

jakarman
Barite | Level 11

Looks as a moving calculation like a moving average. There are many smarter solutions for that.

---->-- ja karman --<-----
jakarman
Barite | Level 11

@hhchenfx, converting a sequential process to one that goes for a divide an conquer approach will usually result in a even worse performance unless you have a fit in the infrastructure.

Luckily enough you can go for that infrastructure fit with grid-computing and/or the hadoop way. You have just describe the principles of those,   
 

---->-- ja karman --<-----

hackathon24-white-horiz.png

2025 SAS Hackathon: There is still time!

Good news: We've extended SAS Hackathon registration until Sept. 12, so you still have time to be part of our biggest event yet – our five-year anniversary!

Register Now

How to Concatenate Values

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.

SAS Training: Just a Click Away

 Ready to level-up your skills? Choose your own adventure.

Browse our catalog!

Discussion stats
  • 6 replies
  • 2068 views
  • 3 likes
  • 5 in conversation