The Macro Processor
Page 1. You can refer to page 339 of our textbook for an example of a program that SAS would need to pre-process before executing the code. In that particular case, before executing the code, SAS would have to run the program through the macro processor in order to replace all the occurrences of "&NUMBER" with the value "5".
Substituting text with %LET
Page 3. In case you want to try the program out on your own, here it is:
OPTIONS PS = 58 LS = 72 NODATE NONUMBER;
DATA models;
infile DATALINES truncover;
input Model $ 1-12 Class $ Price Frame$ 28-38;
DATALINES;
Black Bora Track 796 Aluminum
Delta Breeze Road 399 CroMoly
Jet Stream Track 1130 CroMoly
Mistral Road 1995 Carbon Comp
Nor'easter Mountain 899 Aluminum
Santa Ana Mountain 459 Aluminum
Scirocco Mountain 2256 Titanium
Trade Wind Road 759 Aluminum
;
RUN;
%LET bikeclass = Mountain;
*Use a macro variable to subset;
PROC PRINT DATA = models NOOBS;
where Class = "&bikeclass";
format Price dollar6.;
title "Current Models of &bikeclass Bicycles";
RUN;
Model | Class | Price | Frame |
---|---|---|---|
Nor'easter | Mountain | $899 | Aluminum |
Santa Ana | Mountain | $459 | Aluminum |
Scirocco | Mountain | $2,256 | Titanium |
You might also want to change the value of Mountain in the %LET statement to, say, Road, and re-run the program to see the effect.
Creating Modular Code with Macros
Page 4. Again, in case you want to try the program out on your own, here it is:
%MACRO printit;
PROC PRINT data = models NOOBS;
title 'Current Models';
var Model Class Frame Price;
format Price dollar6.;
RUN;
%MEND printit;
%printit
PROC SORT data = models;
by Price;
RUN;
%printit
Adding Parameters to Macros
Page 6. Here's the code for the example:
%MACRO sortandprint(sortseq=, sortvar=);
PROC SORT data = models;
by &sortseq &sortvar;
RUN;
PROC PRINT data = models noobs;
title 'Current Models';
title2 "Sorted by &sortseq &sortvar";
var Model Class Frame Price;
format price dollar6.;
RUN;
%MEND sortandprint;
%sortandprint(sortseq=Descending, sortvar=Price)
%sortandprint(sortseq=, sortvar=Class)
Page 7. Here's the code for the example with the MPRINT option invoked:
OPTIONS MPRINT;
%MACRO sortandprint(sortseq=, sortvar=);
PROC SORT data = models;
by &sortseq &sortvar;
RUN;
PROC PRINT data = models noobs;
title 'Current Models';
title2 "Sorted by &sortseq &sortvar";
var Model Class Frame Price;
format price dollar6.;
RUN;
%MEND sortandprint;
%sortandprint(sortseq=Descending, sortvar=Price)
%sortandprint(sortseq=, sortvar=Class)
Conditional Logic
Page 9. Here's the program:
DATA orders;
input CustomerID $ 1-3 @5 OrderDate date7. Model $ 13-24 Quantity;
DATALINES;
287 15OCT03 Delta Breeze 15
287 15OCT03 Santa Ana 15
274 16OCT03 Jet Stream 1
174 17OCT03 Santa Ana 20
174 17OCT03 Nor'Easter 5
174 17OCT03 Scirocco 1
347 18OCT03 Mistral 1
287 21OCT03 Delta Breeze 30
287 21OCT03 Santa Ana 25
;
RUN;
%MACRO reports;
%IF &SYSDAY = Monday %THEN %DO;
PROC PRINT data = orders NOOBS;
format OrderDate date7.;
title "&SYSDAY Report: Current Orders";
RUN;
%END;
%ELSE %IF &SYSDAY = Friday %THEN %DO;
PROC TABULATE data = orders;
class CustomerID;
var Quantity;
table CustomerID ALL, Quantity;
title "&SYSDAY Report: Summary of Orders";
RUN;
%END;
%MEND reports;
%REPORTS
By the way, you might notice that I embedded the RUN; statements in the macro, rather than placing them outside of the macro as the authors of the paper did. Either approach works... it's just a matter of preference.
Data-driven Programs
Page 12. Here's the program:
*Sort by Quantity;
PROC SORT data = orders;
by descending Quantity;
RUN;
*Use CALL SYMPUT to find the biggest order;
DATA _NULL_;
set orders;
if _N_ = 1 then CALL SYMPUT("biggest", CustomerID);
else STOP;
RUN;
*Print all obs for customer with biggest order;
PROC PRINT data = orders NOOBS;
where CustomerID = "&biggest";
format OrderDate date7.;
title "Customer &biggest Had the Single Largest Order";
RUN
CustomerID | OrderDate | Model | Quantity |
---|---|---|---|
28 | 21OCT00 | Santa Ana | 25 |
28 | 15OCT00 | Santa Ana | 15 |
28 | 15OCT00 | Delta Breez | . |
28 | 21OCT00 | Delta Breez | . |