Macro Essential


In [2]:
libname orion '/folders/myshortcuts/_myfolders/ecmac193';


Out[2]:

32   ods listing close;ods html5 file=stdout options(bitmap_mode='inline') device=png; ods graphics on / outputfmt=png;
NOTE: Writing HTML5 Body file: STDOUT
33
34 libname orion '/folders/myshortcuts/_myfolders/ecmac193';
NOTE: Libref ORION was successfully assigned as follows:
Engine: V9
Physical Name: /folders/myshortcuts/_myfolders/ecmac193
35 ods html5 close;ods listing;

36

Lesson 4: Creating and Using Macro Programs

When a macro is compiled, any macro language statements within it are checked for syntax errors. If there are errors, the macro processor will create a non-executable macro. SAS language statements in a macro definition are not checked for syntax errors until the macro is executed.

Three steps to create and use a macro: define the macro, complile th macro, and call the Macro

Defining, Compiling, and Calling a Macro


In [3]:
/*Macro 1*/

options mcompilenote = none;
%macro puttime;
%put The current time is %sysfunc(time(),timeampm.).;
%mend puttime;
/*Macro 2*/
options mcompilenote = all; /*default = none*/
%macro prtlast;
proc print data=&syslast (obs=10);
title "Listing of &syslast data set";
run;
%mend;
options mprint;
%prtlast


Out[3]:

38   ods listing close;ods html5 file=stdout options(bitmap_mode='inline') device=png; ods graphics on / outputfmt=png;
NOTE: Writing HTML5 Body file: STDOUT
39
40 /*Macro 1*/
41 %let path =/folders/myshortcuts/_myfolders/ecmac193;
42 libname orion "&path";
NOTE: Libref ORION was successfully assigned as follows:
Engine: V9
Physical Name: /folders/myshortcuts/_myfolders/ecmac193
43 options mcompilenote = none;
44 %macro puttime;
45 %put The current time is %sysfunc(time(),timeampm.).;
46 %mend puttime;
47 /*Macro 2*/
48 options mcompilenote = all; /*default = none*/
49 %macro prtlast;
50 proc print data=&syslast (obs=10);
51 title "Listing of &syslast data set";
52 run;
53 %mend;
NOTE: The macro PRTLAST completed compilation without errors.
5 instructions 136 bytes.
54 options mprint;
55 %prtlast
MPRINT(PRTLAST): proc print data=_NULL_ (obs=10);
MPRINT(PRTLAST): title "Listing of _NULL_ data set";
MPRINT(PRTLAST): run;
NOTE: No variables in data set WORK._NULL_.
NOTE: PROCEDURE PRINT used (Total process time):
real time 0.00 seconds
cpu time 0.00 seconds

56 ods html5 close;ods listing;

57

SAS Studio stores macro definitions in the work.sasmac1 catalog. This catalog can be accessed by running a PROC CATALOG step. SAS University Edition stores the Macro in work.sasmacr though.


In [4]:
proc catalog cat=work.sasmacr;
contents;
title "My Temporary Macros";
quit;
title;


Out[4]:
SAS Output

My Temporary Macros

Contents of Catalog WORK.SASMACR
# Name Type Create Date Modified Date Description
1 PRTLAST MACRO 06/14/2017 18:50:58 06/14/2017 18:50:58  
2 PUTTIME MACRO 06/14/2017 18:50:58 06/14/2017 18:50:58  

data work.customers; set orion.customer; keep Customer_ID Country Customer_Name; run; %prtlast proc sort data=work.customers out=work.sort_customers; by Country; run; %prtlast /Note that the titles differ/ When you call a macro in your SAS program, the word scanner passes the macro call to the macro processor, which then searches the default catalog, work.sasmacr for the entry corresponding to that macro. Then it executes any compiled macro language statements within the macro and sends any remaining text to the input stack for word scanning. When the SAS compiler receives a global SAS statement, or when it encounters a SAS step boundary, the macro processor suspends macro execution. After the SAS code executes, the macro processor resumes execution of macro language statements. /Check the log/ options nomprint; %let dsn = orion.city; %let vars = City_Name Country; %prtlast options mprint; %let dsn = orion.city; %let vars = City_Name Country; %prtlast options nomprint; Practice: Defining and Calling a Macro Task Define a macro that prints selected customers from the SAS data set orion.customer_dim, based on the value of the macro variable Type. Then call the macro specifying different values for Type. Reminder: Make sure you’ve defined the Orion library. Copy and paste the following code into the editor: 2 Convert the program into a macro named Customers. Set the appropriate system option to display a note in the SAS log when the macro definition has compiled. Submit the macro definition and examine the log. Submit a %LET statement to assign the value Gold to the macro variable Type. Call the macro, examine the log and view the results. Activate the appropriate system option to display source code received by the SAS compiler. Call the macro again, examine the log and view the results. options mcompilenote=all; %macro Customers; title "&type Customers"; proc print data=orion.customer_dim; var Customer_Name Customer_Gender Customer_Age; where Customer_Group contains "&type"; run; title; %mend Customers; %let type = Gold;options mprint; %Customers /Change the value of Type to Internet./ %let type=Internet; options mprint; %Customers proc catalog catalog = work.sasmacr; contents; run; Practice: Calling a Macro from a TITLE Statement Task In this practice, you define a macro program named Currtime that displays the current time. Then you print selected observations from the SAS data set orion.customer_dim and reference the Currtime macro in the title for this report. Reminder: Make sure you’ve defined the Orion library. Define a macro that calls the SAS function, TIME, and displays it in the TIMEAMPM. format. Name the macro Currtime. Submit the macro definition. Copy and paste the following code into the editor. 3 title 'Customer List'; proc print data=orion.customer_dim(obs=10); var Customer_Name Customer_Group; run; title; Add a TITLE2 statement. Call the macro Currtime from the TITLE2 statement. Submit the program and examine the results. Enable the MPRINT option, resubmit the code, and view the results. Are any messages generated by MPRINT? Why or why not? Although you enabled the MPRINT option, SAS does not display any MPRINT messages in the log. This is because the Currtime macro does not generate any SAS code. It simply calls %SYSFUNC to invoke the TIME function. SAS formats the returned value, places it on the input stack and uses it in the TITLE statement. SAS does not display the function or the returned value in the log. %macro currtime; %sysfunc(time(), TIMEAMPM.) %mend currtime; options mprint; title "Customer List"; title2 "%currtime"; proc print data=orion.customer_dim(obs=10); var Customer_Name Customer_Group; run; title; options nomprint; Although you enabled the MPRINT option, SAS does not display any MPRINT messages in the log. This is because the Currtime macro does not generate any SAS code. It simply calls Using Macro Parameters to replace using several %let statements Positional Parameters Positional parameters use a one-to-one correspondence between the parameter names in the macro definition and the parameter values supplied in the macro call. When you call a macro, SAS automatically creates a macro variable for each parameter. The values listed in a macro call can be text, macro variable references, macro calls, or null values. SAS assigns these values to the parameter variables using a one-to-one correspondence. / The TABLE statement that requests a one-way frequency table on Order_Type and optionally could request statistics. The statistics are specified using the opts macro variable./ 4 options mcompilenote = all; %macro count (opts, start, stop); proc freq data=orion.orders; where order_date between "&start"d and "&stop"d; table order_type / &opts title1 "Orders from &start to &stop"; run; %mend count; options mprint; %count() /This selects nothing from the dataset, unlike keyword parameters through which default values are inputted/ /NOTE: No observations were selected from data set ORION.ORDERS. NOTE: There were 0 observations read from the data set ORION.ORDERS./ %count(nocum,01jan11,31dec11) %count(,01jul11,31dec11) The values of automatic macro variables are always stored in the global symbol table. They are always available in your SAS session. Whenever you call a macro that includes a parameter list, SAS creates a local symbol table which stores the macro variable values created by calling the macro. SAS deletes the local symbol table when the macro finishes execution. That is, the local symbol table exists only while the macro executes. Keyword Parameters %macro count(opts=,start=01jan011,stop=31dec11); /01jan011 and others (including null) become the default values/ proc freq data=orion.orders; where order_date between"&start"d and "&stop"d; table order_type / &opts title1 "Orders from &start to &stop"; run; %mend count; %count() %count(opts=nocum) %count(stop=01jul11,opts=nocum nopercent) You must list all positional parameters in the %MACRO statement before any keyword parameters. You must list the positional values before any keyword values when you call a mixed parameter list macro. %macro count (opts,stop=31dec11,start=01jan011); proc freq data=orion.orders; 5 where order_date between"&start"d and "&stop"d; table order_type / &opts title1 "Orders from &start to &stop"; run; %mend count; %count(nocum nopercent,stop=30jun11) /List the positional parameter value first./ Practice: Defining and Using Macro Parameters I Task In this practice, you define and call a macro program using positional and keyword parameters. The Customers macro program prints observations based on the value of the macro variable Type. Reminder: Make sure you’ve defined the Orion library. Copy and paste the following code into the editor: %macro customers; title "&type Customers"; proc print data=orion.customer_dim; var Customer_Name Customer_Gender Customer_Age; where Customer_Group contains "&type"; run; title; %mend customers; Convert this program into a macro with a positional parameter. Name the parameter based on macro variable references within the program. Set the appropriate system option to display a note in the SAS log when a macro definition has compiled. Submit the macro definition to compile the macro. Set the MPRINT option. Call the macro defined in the previous step with a value of Gold for the parameter and view the results. Call the macro again, but with a parameter value of Catalog and view the results. Change the positional parameter to a keyword parameter with a default value of Club. Submit the revised macro definition to compile the macro. Call the macro defined in the previous step with a value of Internet for the keyword parameter and view the results. Call the macro again, but allow the macro to use its default parameter value. View the results. %macro customers_p (type); title "&type Customers"; proc print data=orion.customer_dim; var Customer_Name Customer_Gender Customer_Age; 6 where Customer_Group contains "&type"; run; title; %mend customers_p; options mprint; %customers_p(Gold) %customers_p(Catalog) %macro customers_k (type = Club); title "&type Customers"; proc print data=orion.customer_dim; var Customer_Name Customer_Gender Customer_Age; where Customer_Group contains "&type"; run; title; %mend customers_k; %customers_k() %customers_k(Type=Internet) Practice: Defining and Using Macro Parameters II Task In this practice, you define and call a macro program that will generate PROC MEANS code. The program calculates statistics based on analysis variables listed in the VAR statement and grouped by variables listed in the CLASS statement. Reminder: Make sure you’ve defined the Orion library. Copy and paste the following code into the editor: options nolabel; title 'Order Stats'; proc means data=orion.order_fact maxdec=2 mean; var total_retail_price; class order_type; run; title; Create a macro with keyword parameters that generalizes the code so that the following attributes are controlled by macro variables. Choose default values for all parameters so that the code executes correctly. Use the following values: Statistics: any combination of: N, NMISS, MIN, MEAN, MAX, RANGE, or a null value Decimal places: 0, 1, 2, 3, or 4 Analysis variables: Total_Retail_Price and/or Costprice_Per_Unit Class variables: Order_Type and/or Quantity Execute the macro using the default parameter values. View the results. 7 Call the macro again, using the appropriate parameter values to produce this report. Call the macro again, but override only the default parameter values for statistics and decimal places to produce this this report. options nolabel; title 'Order Stats'; proc means data=orion.order_fact maxdec=2 mean; var total_retail_price; class order_type; run; title; %macro orderstats (var = Total_Retail_Price, class = order_type, decimals=2, stats = mean); options nolabel; title 'Order Stats'; proc means data=orion.order_fact &stats maxdec= &decimals var &var class &class run; title; %mend orderstats; %orderstats() %orderstats(var=costprice_per_unit, class=quantity, stats=min mean max, decimals=0) %orderstats(stats=min mean max, decimals=0) A macro definition must begin with a %MACRO statement and must end with a %MEND statement. The macro definition can include macro language statements as well as SAS language statements. When the macro is compiled, macro language statements are checked for syntax errors. The compiled macro is stored in a temporary SAS catalog by default. Mixed Parameters In a mixed parameter list, positional parameters must be listed before any keyword parameters. Both positional and keyword parameters create macro variables in the local symbol table. When you omit a keyword parameter from the macro call, the default value for that parameter is used. When you submit a macro definition, the macro is compiled and is stored in a SAS catalog. When you call the macro, the macro is executed. The macro is available for execution anytime throughout the current SAS session. The text within a macro definition can include constant text, SAS data set names, SAS variable names, SAS statements, macro variables, macro functions, macro program statements, and any combination of the above. 8 When you submit a call to a compiled macro, the macro is executed. When the macro processor receives the macro call, it searches the default catalog, work.sasmacr, for the entry corresponding to that macro. Then it executes any compiled macro language statements within the macro. When SAS language statements are encountered, the macro processor places these statements onto the input stack and pauses while they are passed to the compilverbatimer and then executed. Then the macro processor continues to repeat these steps until the %MEND statement is reached. proc catalog cat=work.sasmacr; contents; quit; List the contents of the Sasmacr catalog as output 9