Help using Base SAS procedures

Position of %END;

Reply
Frequent Contributor
Posts: 75

Position of %END;

%MACRO MERGE;
%Do RO=1 %to 5;
PROC SORT DATA = MERGED_&RO; BY KEY;%END; RUN;

/*what if %END; is placed after RUN*/


%MEND;

Hi

 

 

I would like to know how SAS process a Macro DO-loop.

 

Should I place the %END after RUN or before?

 

If it is placed before RUN, does it mean that the DO-Loop substitute from MERGED_1 to MERGED_5 but it only executes the Proc Sort for MERGED_5?

 

Thank you

Trusted Advisor
Posts: 1,381

Re: Position of %END;

If you look at the log youu will see that RUN is after all sorts.

In this specific case, as 2nd sort is independent of first that realy soesn't matter,

but as a rule better put the %END after RUN, so that each PROC or datastep has its own RUN.

Super User
Posts: 6,939

Re: Position of %END;

A PROC statement always constitutes a step boundary (as does a RUN statement), so all PROC SORT's will be executed.

---------------------------------------------------------------------------------------------
Maxims of Maximally Efficient SAS Programmers
Super User
Posts: 5,083

Re: Position of %END;

Macro language is not processing your data.  It is generating a program.  With %END in its current location, the generated program looks like this:

 

PROC SORT DATA=MERGED_1; BY KEY;

PROC SORT DATA=MERGED_2; BY KEY;

PROC SORT DATA=MERGED_3; BY KEY;

PROC SORT DATA=MERGED_4; BY KEY;

PROC SORT DATA=MERGED_5; BY KEY;

RUN;

 

Now it becomes a question of how SAS language would handle this program.  The same principles apply with %END moved to after the RUN statement.  Then the generated SAS code would look like this:

 

PROC SORT DATA=MERGED_1; BY KEY; RUN;

PROC SORT DATA=MERGED_2; BY KEY; RUN;

PROC SORT DATA=MERGED_3; BY KEY; RUN;

PROC SORT DATA=MERGED_4; BY KEY; RUN;

PROC SORT DATA=MERGED_5; BY KEY; RUN;

 

Again, SAS language receives this code, interprets it, and executes it.  But macro language is never processing the data, only generating the program.

 

I agree with everything that Kurt wrote, including the suggestion to move the %END statement so that every PROC SORT will have its own RUN statement.

Super User
Super User
Posts: 7,401

Re: Position of %END;

Whilst the guys have answered the techinical part above I would also like to add that making your program readable should be your number 1 priority (unless your dealing with big data).  To this end use lower and consistent case, indent blocks etc.:

%macro merge ();
  %do ro=1 %to 5;
    proc sort data=merged_&ro.;
      by key;
    run;
  %end;
%mend merge;

You will note the dot after the macro variable - not vital, but highlights nicely in the editor, other things like %mend <macro name> rather than just %mend.  At the end of the day other people have to look at your code.

Also, a further note, the macro above is pretty much useless.  You have create a problem for yourself in code before this by creating separate datasets for the same data as indicated by the merged_1-5.  It is rarely a good idea to split up same data, as then each time you code you need to loop over it.  A simpler method - if you just had the 5 datasets:

data want;
  set merged_:;
run;
proc sort data=want;
  by key;
run;

You could use the indsname option to get filename if necessary.

Ask a Question
Discussion stats
  • 4 replies
  • 211 views
  • 3 likes
  • 5 in conversation