Вы находитесь на странице: 1из 59

/*L1-practice1*/

/*
* Practice 1: Reference an Automatic Macro Variable
* Lesson 1 - Introducing Macro Variables
* SAS Macro Language 1: Essentials
*/
/* Task:
In this practice, you create a report that includes system information that is
provided by automatic macro variables.
Reminder: Make sure you've defined the Orion library.
Copy and paste the following PROC PRINT step into the editor:
proc print data=orion.customer_dim;
run;
Add a FOOTNOTE statement that displays today's date (assuming you started your SAS
session today) by using an automatic macro variable. Use this text for your
footnote: Report Created on ddmmmyy
Submit the program and examine the results.
Scroll to the bottom of the output and verify that the footnote contains today's
date (assuming that you began the current SAS session today).
*/

proc print data=orion.customer_dim;


footnote "Report Created on &sysdate"; /*use "..." for macro var*/
run;

/*L1-practice2*/

/*
* Practice 2: Create and Reference a Macro Variable
* Lesson 1 - Introducing Macro Variables
* SAS Macro Language 1: Essentials
*/
/* Task:
In this practice, you replace values that are hardcoded in a program with
references to a macro variable.
The data set orion.customer contains information about customers from multiple
countries.
Reminder: Make sure you've defined the Orion library.
Submit the following program to print observations about customers from Germany,
and view the results.
title 'Customers in DE';
proc print data=orion.customer;
var Customer_ID Customer_Name Gender;
where Country='DE';
run;
Modify the program to replace each instance of the value DE with a reference to a
macro variable. Name the macro variable location and set its value to DE. Submit
the program and verify that the results are the same as the original program's
results.
Edit the program to print information about customers from South Africa (ZA)
instead of Germany, and resubmit it. View the results.
*/

%let Location = DE;

title "Customers in &location"; /*use "..." for macro var*/


proc print data=orion.customer;
var customer_id customer_name gender;
where country="&location";
run;

%let Location = ZA;

title "Customers in &location"; /*use "..." for macro var*/


proc print data=orion.customer;
var customer_id customer_name gender;
where country="&location";
run;

/*L1-practice3*/

/*
* Practice 3: Write a SAS Program that References a Macro Variable
* Lesson 1 - Introducing Macro Variables
* SAS Macro Language 1: Essentials
*/
/* Task:
Write a program to print salary information that's stored in
orion.employee_payroll. The program needs to create and reference a macro variable.
After you submit the program and view the output, edit the value of the macro
variable to change the results.
Reminder: Make sure you've defined the Orion library.
Write a program to print information from orion.employee_payroll about all
employees who earn at least a designated minimum salary. The salary data is stored
in the variable Salary. Use a macro variable named minsal to store the value of the
minimum salary and set its initial value to 60000.
%let minsal = 60000;
proc print data=orion.employee_payroll;
where Salary >= &minsal;
run;
Add a statement to format Birth_Date, Employee_Hire_Date, and Employee_Term_Date
with the DATE9. format and Salary with the DOLLAR8. format.
Add a TITLE statement that uses minsal in the title Employees Earning 60000 or
More.
Submit the program and view the results.
Modify the program so that the report includes only those employees who earn at
least 100000.
Submit the program and view the results.
*/

%let minSal = 60000;

title "Employees Earning &minSal or More"; /*use "..." for macro var*/
proc print data=orion.employee_payroll;
where salary >= &minSal;
/*format all var with the DATE9. format*/
format Birth_Date Employee_Hire_Date Employee_Term_Date date9.
Salary DOLLAR8.;
run;

/* Modify the program so that the report includes


only those employees who earn at least 100000. */

%let minSal = 100000;


title "Employees Earning &minSal or More"; /*use "..." for macro var*/
proc print data=orion.employee_payroll;
where salary >= &minSal;
/*format all var with the DATE9. format*/
format Birth_Date Employee_Hire_Date Employee_Term_Date date9.;
run;

/*L1-practice4*/

/*
* Practice 4: Display Resolved Macro Variables in the SAS Log
* Lesson 1 - Introducing Macro Variables
* SAS Macro Language 1: Essentials
*/
/* Task:
Use the SYMBOLGEN system option and the %PUT statement to display resolved macro
variables in the SAS log.
Reminder: Make sure you've defined the Orion library.
Copy and paste the following code into the editor:
%let type=Internet;
proc print data=orion.customer_dim;
var Customer_Name Customer_Gender Customer_Age;
where Customer_Group contains "&type";
title "&type Customers";
run;
Add an OPTIONS statement before the %LET statement to activate the SYMBOLGEN system
option. Submit the program. Then examine the SAS log and the results.
In the log, you will see two SYMBOLGEN messages, one for each reference to the
macro variable Type. Modify the OPTIONS statement to deactivate the SYMBOLGEN
system option.
Add a %PUT statement at the end of the program to display the value of the macro
variable Type. Submit the revised program and examine the SAS log. You can put any
text in your %PUT statement.
*/

OPTIONS NOSYMBOLGEN;

%let type=Internet;

proc print data=orion.customer_dim;


var Customer_Name Customer_Gender Customer_Age;
where Customer_Group contains "&type";
title "&type Customers";
run;

%put The value of macro variable Type is &type;


title;

/*L1-practice5*/

/*
* Practice 5: Combine Macro Variable References with Text
* Lesson 1 - Introducing Macro Variables
* SAS Macro Language 1: Essentials
*/
/* Task:
In this practice you reference consecutive macro variables using the
orion.organization_dim data set.
Reminder: Make sure you've defined the Orion library.
Copy and paste the following code into the editor:
proc print data=orion.organization_dim;
where Employee_Hire_Date="01AUG2006"d;
id Employee_ID;
var Employee_Name Employee_Country Employee_Hire_Date;
title 'Personal Information for Employees Hired in AUG 2006';
run;
Revise the program so that the two occurrences of AUG and 2006 are replaced by
references to the macro variables month and year, respectively. Assign the value
AUG to month and the value 2006 to year. Submit the program and view the results.
Revise the program again. Change the value of month to JUL and year to 2003.
Resubmit the program and view the results.
*/

/*1. Revise*/
OPTIONS SYMBOLGEN;

/*create a macro variable that stores the month value*/


%let month=AUG;
/*create a macro variable that stores the year value*/
%let year=2006;

proc print data=orion.organization_dim;


where Employee_Hire_Date="01&month&year"d;
id Employee_ID;
var Employee_Name Employee_Country Employee_Hire_Date;
title 'Personal Information for Employees Hired in &month &year';
run;

OPTIONS NOSYMBOLGEN;

/*2. Revise*/
OPTIONS SYMBOLGEN;

/*create a macro variable that stores the month value*/


%let month=JUL;
/*create a macro variable that stores the year value*/
%let year=2003;

proc print data=orion.organization_dim;


where Employee_Hire_Date="01&month&year"d;
id Employee_ID;
var Employee_Name Employee_Country Employee_Hire_Date;
title 'Personal Information for Employees Hired in &month &year';
run;

OPTIONS NOSYMBOLGEN;

/*L1-practice6*/

/*
* Practice 6: Combine Macro Variable References with Special Characters
* Lesson 1 - Introducing Macro Variables
* SAS Macro Language 1: Essentials
*/
/* Task:
Reference consecutive macro variables in a SAS program that prints selected
information from the orion.organization_dim data set.
Reminder: Make sure you've defined the Orion library.
The following program prints selected information from the orion.organization_dim
data set. Submit the program and view the results.
proc print data=orion.organization_dim;
id Employee_ID;
var Employee_Name Employee_Country Employee_Gender;
title 'Listing of All Employees From orion.organization_dim';
run;
Modify the program so that all occurrences of organization and Employee are
replaced with the macro variable references dsn and var respectively. When
substituting for the hardcoded Employees in the TITLE statement, be sure to keep
the ending s as part of the title text. Submit the program and verify that the
results are the same as the original program's results.
Revise the program again. Modify the value of dsn to customer and var to Customer.
Resubmit the program and view the results.*/

/* 1. Revise */
%let dsn=organization;
%let var=Employee;

proc print data=orion.&dsn._dim;


id &var._ID;
var &var._Name &var._Country &var._Gender;
title "Listing of All &var.s From orion.&dsn._dim"; /*use "..."*/
run;

/* 2. Revise */
%let dsn=customer;
%let var=Customer;

proc print data=orion.&dsn._dim;


id &var._ID;
var &var._Name &var._Country &var._Gender;
title "Listing of All &var.s From orion.&dsn._dim"; /*use "..."*/
run;

/*L1.1-Using_Automatic_Macro_Variable*/

/*
* Lesson 1.1: Using Automatic Macro Variable
* Lesson 1 - Introducing Macro Variables
* SAS Macro Language 1: Essentials
*/
/*
* Using Automatic Macro Variable
*/

/*
* This step prints the contents of the orion.customer_type data set.
* The footnotes list the time, day, and date that the SAS session began,
* as well as the operating system and SAS version.

proc print data=orion.customer_type noobs;


title 'Listing of Customer_Type Data Set';
footnote1 'Created 09:35 Wednesday, 05SEP2012';
footnote2' on the WIN System Using SAS 9.3';
run;
* Notice that the footnotes display the information that the program specified.
* This information might not be current.
*/

/*
* Change the FOOTNOTE statements, as shown below,
* so that they contain references to automatic macro variables.
* Be sure to change the single quotation marks to double quotation marks
* or the macro processor won't be able to resolve these macro variable references.
*/

proc print data=orion.customer_type noobs;


title 'Listing of Customer_Type Data Set';
footnote1 "Created &SYSTIME &SYSDAY, &SYSDATE9"; /*use double quotation marks*/
footnote2 "on the &SYSSCP System Using SAS Release &SYSVER"; /*use double quotation
marks*/
run;

/*L1.2-User_Defined_Macro_Variable*/

/*
* Lesson 1.2: Creating and Referencing a User-Defined Macro Variab
* Lesson 1 - Introducing Macro Variables
* SAS Macro Language 1: Essentials
*/
/*
* Creating and Referencing a User-Defined Macro Variable
* edit a program to use a macro variable that you create instead of hardcoded
values
*/

/*
* Edit a program to use a macro variable
* that you create instead of hardcoded values

proc print data=orion.order_fact;


where year(order_date)=2010;
title "Orders for 2010";
run;
proc means data=orion.order_fact mean;
where year(order_date)=2010;
class order_type;
var total_retail_price;
title "Average Retail Price for 2010";
title2 "by Order_Type";
run;
* This program tracks orders for the year 2010.
*/

/*
* Suppose you want to to see the orders for 2011 instead?
* It would be much simpler if the program referred
* to a macro variable that held the value of the year
* instead of having those values hardcoded.
*/
/*create a macro variable named Year = 2011*/
%let year = 2011;

proc print data=orion.order_fact;


where year(order_date) = &year;
title "Orders for &year"; /*use "..." for macro var*/
run;

proc means data=orion.order_fact mean;


where year(order_date) = &year;
class order_type;
var total_retail_price;
title "Average Retail Price for &year"; /*use "..." for macro var*/
title2 "by Order_Type"; /*use "..." for macro var*/
run;

/*L1.3-Using_PUT_Statement_to_Display_Macro_Var_Values*/

/*
* Lesson 1.3: Using the %PUT Statement to Display Macro Variable Values
* Lesson 1 - Introducing Macro Variables
* SAS Macro Language 1: Essentials
*/
/*
* Displaying Macro Variables in the SAS Log
* Using the %PUT Statement to Display Macro Variable Values
*/

/*list the names and values of all user-defined macro variables*/


%PUT _user_;

/* list all macro variables, both user-defined and automatic*/


%PUT _all_;
/*the log also displays a label for each macro variable:
GLOBAL for user-defined macro variables
and AUTOMATIC for automatic macro variables */

/*L1.4-Using_PUT_Statement_to_Display_Macro_Var_Values*/

/*
* Lesson 1.4: Using the SYMBOLGEN System Option
* Lesson 1 - Introducing Macro Variables
* SAS Macro Language 1: Essentials
*/
/*
* Displaying Macro Variables in the SAS Log
* Using the SYMBOLGEN System Option
*/

/*turn on the SYMBOLGEN option*/


OPTIONS SYMBOLGEN;

%let year=2011;
proc print data=orion.order_fact;
where year(order_date)=&year;
title "Orders for &year";
run;

proc means data=orion.order_fact mean;


where year(order_date)=&year;
class order_type;
var total_retail_price;
title "Average Retail Price for &year";
title2 "by Order_Type";
run;

/*L1.5-Placing_Text_before_or_after_MacroVarRef*/

/*
* Lesson 1.5: Placing Text before / after a Macro Variable Reference
* Lesson 1 - Introducing Macro Variables
* SAS Macro Language 1: Essentials
*/
/*
* Processing Macro Variables
* 1. Placing Text before a Macro Variable Reference
* 2. Referencing Adjacent Macro Variables
* 3. Placing Text after a Macro Variable Reference
*/

/*
proc chart data=temp.y2011&jun;
hbar week / sumvar=sale;
run;
proc plot data=temp.y2011&jun;
plot sale*day;
run;
*/

/* Enable both the month and the year to be substituted */

/*creating a macro variable that stores the month value*/


%let month=jun;
/*creating a macro variable that stores the year value*/
%let year=2011;
/*creating a macro variable that stores the analysis variable value*/
%let var=Sale;

proc chart data=temp.y&year&month; /*(1, 2)*/


hbar week / sumvar=&var;/*(1)*/
run;
proc plot data=temp.y&year&month; /*(1, 2)*/
plot &var*day; /*(3)*/
run;

/*L1.6-Delimiting_Macro_Variable_Reference*/
/*
* Lesson 1.6: Delimiting a Macro Variable Reference
* Lesson 1 - Introducing Macro Variables
* SAS Macro Language 1: Essentials
*/
/*
* Processing Macro Variables
* Delimiting a Macro Variable Reference
*/

/*
* Modify the previous program (1.5) so that it's easy
* to switch between using the CHART and PLOT procedures
* of Base SAS software
* and the GCHART and GPLOT procedures of SAS/GRAPH software.
*
* You can set the value of the macro variable graphics
* to determine which procedure to invoke.
* When the value of graphics resolves to g,
* the program invokes PROC GCHART.
* When the value of graphics is null,
* the program invokes PROC CHART .
*/

/* GRAPHICS should be null or G*/


%let graphics=g;
/* enable both the month and the year to be substituted */
/*creating a macro variable that stores the month value*/
%let month=jun;
/*creating a macro variable that stores the year value*/
%let year=2011;
/*creating a macro variable that stores the analysis variable value*/
%let var=Sale;

/* wrong solution
proc &graphicschart data=temp.y&year&month;
hbar week / sumvar=&var;
run;
proc &graphicsplot data=temp.y&year&month;
plot &var*day;
run;
*/
/*The messages in the log reveal problems with this program.
Notice that the warning message indicates that
the macro variable graphicschart was not resolved.
Also notice the error message.
It indicates that SAS expected the name of the procedure
to be executed.
SAS interprets the macro variable's name to be graphicschart
instead of graphics because there's no delimiter
between the macro variable reference, &graphics,
and the trailing text, chart.
Graphicschart is a valid name token, so the word scanner
passes the macro trigger &graphicschart to the macro processor.*/

/*
* To correct this program, you need to add a period after
* the reference to the macro variable graphics.
* A period (.) is a special delimiter that ends
* a macro variable reference.
*/
proc &graphics.chart data=temp.y&year&month; /*use period (.) as delimiter*/
hbar week / sumvar=&var;/*(1)*/
run;
proc &graphics.plot data=temp.y&year&month; /* use period (.) as delimiter*/
plot &var*day; /*(3)*/
run;

/* The period is treated as part of the macro variable reference and does not
appear
when the macro variable is resolved.*/

/*L1.7-Working_with_Values_That_Contain_Delimiters*/

/*
* Lesson 1.7: Working with Values That Contain Delimiters
* Lesson 1 - Introducing Macro Variables
* SAS Macro Language 1: Essentials
*/
/*
* Processing Macro Variables
* - explicitly delimit a macro variable reference
*/

/*
* Modify the previous program (1.6) so
* it include a macro variable that stores the libref
*/

/*create a macro variable that stores the libref value*/


%let lib=temp;
/* GRAPHICS should be null or G*/
%let graphics=g;
/* enable both the month and the year to be substituted */
/*create a macro variable that stores the month value*/
%let month=jun;
/*create a macro variable that stores the year value*/
%let year=2011;
/*create a macro variable that stores the analysis variable value*/
%let var=Sale;

proc &graphics.chart data=&lib..y&year&month; /*use 2 periods (..) - 1st as


delimiter*/
hbar week / sumvar=&var;
run;
proc &graphics.plot data=&lib..y&year&month; /* use 2 periods (..) - 1st as
delimiter*/
plot &var*day;
run;

/* The first period is treated as a delimiter.


The second period is treated as text.
When you use two periods, the compiler receives
the correct library and data set names.*/

/*L2-practice1*/

/*
* Practice 1: Create a New Macro Variable
* Lesson 2 - Using Macro Functions
* SAS Macro Language 1: Essentials
*/
/* Task:
In this practice, you use the %SUBSTR and %SCAN macro character functions to
manipulate character strings and create a new macro variable.
Reminder: Make sure you've defined the Orion library.
Submit a %LET statement to assign the value Anthony Miller
to a macro variable named Fullname.
Extract the first initial and last name,
putting them together into a new macro variable named Newname.
The value of Newname should be A. Miller.
Use the %PUT statement to display the results.
*/

%let Fullname = Anthony Miller;


%let Newname = %substr(&Fullname, 1, 1). %scan(&Fullname, 2);
%put &Newname;

/* Alt Solution
%let Fullname = Anthony Miller;
%let initial = %substr(&Fullname, 1, 1);
%let last_name = %scan(&Fullname, 2);
%let Newname = &initial.. &last;
%put &Newname;
*/

/*L2-practice2*/

/*
* Practice 2: Use Macro Character Functions in a Report
* Lesson 2 - Using Macro Functions
* SAS Macro Language 1: Essentials
*/
/* Task:
In this practice you use a Dictionary table, dictionary.columns, to create a report
that lists the name, type and length of every variable in the orion.country data
set.You then use macro variables and the %SUBSTR and %SCAN functions to modify the
program to display the variables in any data set.
Reminder: Make sure you've defined the Orion library.
Copy and paste the following code into the editor:
title "Variables in the ORION.COUNTRY data set";
proc sql;
select name, type, length
from dictionary.columns
where libname="ORION" and
memname="COUNTRY";
quit;
NOTE: The values of Libname and Memname are stored in upper-case in
dictionary.columns, so the character literals must also be upper-case.##Submit the
program; review the log and output.
Modify the program as follows:
Create the macro variable Dsn and assign it the value orion.country. Replace the
hard coded data set name, orion.country, with a reference to this new macro
variable.
Create two additional macro variables, Lib and Mem. Use the appropriate macro
functions to extract the library name from Dsn and assign it to Lib, and then
extract the single-level data set name from Dsn and assign it to Mem.
Modify the program so that it references the new macro variables in place of the
hard coded values for library name and member name. Remember that the library name
and member name must be in upper-case. Do not assume that the value of Dsn will be
upper-case.
Be sure to use the macro variable references in the TITLE statement as well.
Submit the program and verify that the results are the same as the results from
Step 1.
Modify the program to display the variables in the orion.discount data set instead
of orion.country. Submit the program and verify that it displays the variables in
orion.discount. Check the output.
Submit the following program to create the work.cities data set.
data cities;
set orion.city;
keep city_name country;
run;
Modify the program from Step 4 to display the variables in the most recently
created data set. Hint: Use an automatic macro variable. View the results.
*/

title "Variables in the ORION.COUNTRY data set";


proc sql;
select name, type, length
from dictionary.columns
where libname="ORION" and
memname="COUNTRY";
quit;

/* Modify 1*/
%let dsn = %upcase(orion.country);
%let lib = %scan(&dsn, 1);
%let mem = %scan(&dsn, 2);
title "Variables in the &lib..&mem data set";

proc sql;
select name, type, length
from dictionary.columns
where libname="&lib" and memname="&mem";
quit;

/* Modify 2*/
%let dsn = %upcase(orion.discount);
%let lib = %scan(&dsn, 1);
%let mem = %scan(&dsn, 2);
title "Variables in the &lib..&mem data set";

proc sql;
select name, type, length
from dictionary.columns
where libname="&lib" and memname="&mem";
quit;

/* create the work.cities data set */


data cities;
set orion.city;
keep city_name country;
run;

/* Modify 3*/
%let dsn = %upcase(&syslast);
%let lib = %scan(&dsn, 1);
%let mem = %scan(&dsn, 2);
title "Variables in the &lib..&mem data set";

proc sql;
select name, type, length
from dictionary.columns
where libname="&lib" and memname="&mem";
quit;

/*L2-practice3*/

/*
* Practice 3: Use the %EVAL and %SYSEVALF Functions
* Lesson 2 - Using Macro Functions
* SAS Macro Language 1: Essentials
*/
/* Task:
In this practice, you'll use the %EVAL and %SYSEVALF functions to evaluate
arithmetic expressions and create a new macro variable.
Reminder: Make sure you've defined the Orion library.
1. Copy and paste the following code into the editor. It creates two macro
variables.
%let salary1=25000;
%let salary2=27000;
2. Modify the program by adding statements to compute the difference between the
two salaries and assign it to a third macro variable, Salary_Diff. Add a %PUT
statement to display the value of Salary_Diff. Submit the program and examine the
messages that are written to the SAS log.
3. Revise the program so that the value of Salary2 is 27050.45 and submit the code.
Examine the SAS log.
4. Revise the program so that the assignment statement will work for both integer
and non integer values. Submit the program again and verify that there are no
errors or warnings in the log.
*/

/* 2. */
%let salary1=25000;
%let salary2=27000;
%let salary_diff = %eval(&salary2 - &salary1);
%put The salary difference is &salary_diff;

/* 3. */
%let salary1=25000;
%let salary2=27050.45;
%let salary_diff = %eval(&salary2 - &salary1);
%put The salary difference is &salary_diff;

/* 4. */
%let salary1=25000;
%let salary2=27050.45;
%let salary_diff = %sysevalf(&salary2 - &salary1);
%put The salary difference is &salary_diff;

/*L2-practice4*/

/*
* Practice 4: Using the %SYSFUNC Function
* Lesson 2 - Using Macro Functions
* SAS Macro Language 1: Essentials
*/
/* Task:
In this practice, you use %SYSFUNC to call a SAS date function and create a new
macro variable.
Reminder: Make sure you've defined the Orion library.
1. The SAS MDY function converts a numeric month, day and year to a SAS date. Use
%SYSFUNC to execute the MDY function and format the result with the WEEKDATE.
format and assign it to a macro variable. Use a %PUT statement to display the
result as: Saturday, January 1, 2000.
2. Modify the previous program to find the day of the week on which you were born.
*/

/* 1. */
%let d = %sysfunc(mdy(01,01,2000), weekdate.);
%put &d;

/* 2. */
%let d=%sysfunc(mdy(8,13,1974), weekdate.);
%put &d;

/*L2-practice5*/

/*
* Practice 5: Use Macro Quoting Functions to Create Macro Variables
* Lesson 2 - Using Macro Functions
* SAS Macro Language 1: Essentials
*/
/* Task:
In this practice, you create macro variables and assign values
that require the use of quoting functions
because the values contain special characters.
Reminder: Make sure you've defined the Orion library.
1. Copy and paste the following code into the editor.
Submit the program and examine the log.
%let company=AT&T;
%let list=one;two;
%put list=&list company=&company;
2. Use the appropriate quoting function(s) so that no warning messages are
generated. Ensure that the semicolon following "two" is included as part of the
macro variable List.
*/
/* 1. */
%let company=AT&T;
%let list=one;two;
%put list=&list company=&company;
/* 2. */
%let company = %nrstr(AT&T);
%let list = %str(one; two;);
%put list = &list company = &company;

/*L2-practice6*/

/*
* Practice 6: Use a Macro Quoting Function in a Report
* Lesson 2 - Using Macro Functions
* SAS Macro Language 1: Essentials
*/
/* Task:
In this practice, you create a report that includes values containing special
characters. Use the SAS data set orion.product_dim to create a report that includes
values containing special characters.
Reminder: Make sure you've defined the Orion library.
1. Copy and paste the following code into the editor:
proc print data=orion.product_dim;
where Product_Name contains 'Jacket';
var Product_Name Product_ID Supplier_Name;
title "Product Names Containing 'Jacket'";
run;
2. Submit the program and examine the output. It displays all observations in which
the variable Product_Name contains the word Jacket.
3. Revise the code so that it creates a macro variable named Product with the value
Jacket. Use a macro variable reference instead of the hard coded value in the WHERE
and TITLE statements. Submit the program and verify that it produces the same
results as step 2.
4. Revise the code so that it displays the observations in which the variable
Product_Name contains R&D instead of Jacket. You might need to use a quoting
function to avoid warning messages in the log. Submit the modified program and
check the log to be sure there are no warnings. Then check the output.
*/

/* 1. */

proc print data=orion.product_dim;


where Product_Name contains 'Jacket';
var Product_Name Product_ID Supplier_Name;
title "Product Names Containing 'Jacket'";
run;

/* 3. */
%let product = Jacket;
proc print data=orion.product_dim;
where Product_Name contains "&product";
var Product_Name Product_ID Supplier_Name;
title "Product Names Containing '&product'";
run;

/* 4. */
%let product = %nrstr(R&D);
proc print data=orion.product_dim;
where Product_Name contains "&product";
var Product_Name Product_ID Supplier_Name;
title "Product Names Containing '&product'";
run;

/*L2.1-Manipulating_Char_Strings_Using_Macro_Functions*/

/*
* Lesson 2.1: Manipulating Character Strings Using Macro Functions
* Lesson 2 - Using Macro Functions
* SAS Macro Language 1: Essentials
*/
/*
* Manipulating Character Strings Using Macro Functions
* 1. Using the %SUBSTR Function
* 2. Using the %SCAN Function
* 3. Using the %UPCASE Function
*/

/*** hardcoded program ***


data orders;
set orion.orders;
where 2009 <= year(Order_Date) <= 2017;
run;
title "Listing of ORDERS Data for 2009-2017;
proc print data=orders;
run;
*/

OPTIONS SYMBOLGEN;

/*create startYear Macro var*/


%let startYear = 2009;
/*use the current year for stopyear*/
%let curr_year = %substr(&sysdate9, 6); /*(1.)*/
/*SYSDATE9 --. 19Jun2017, not SYSDATE --. 19Jun17*/

/*create a macro var for data set name*/


%let dsn = orion.orders;
/*separate the data set name from the libref and reuse this value in the DATA
step*/
%let name = %scan(&dsn, 2, .); /*(2.) use '.' as delimiter*/
/*return the second word from the macro variable dsn, using a period as the
delimiter*/

/*create a macro var for analytic variable */


%let analytic_var_name = order_date;

data &name;
set &dsn;
where &startYear <= Year(&analytic_var_name) <= &curr_year;
run;

title "Listing of %upcase(&name) Data for &startYear-&curr_year"; /*(3.)*/

/* use automatic macro variable instead of using the macro variable '&name' */
proc print data=&syslast;
/*SYSLAST stores the name of the most recently created data set in the form
libref.name.*/
run;

OPTIONS NOSYMBOLGEN;

/*L2.2-Manipulating_Char_Strings_Using_INDEX_Function*/

/*
* Lesson 2.1: Manipulating Character Strings Using Macro Functions
* Lesson 2 - Using Macro Functions
* SAS Macro Language 1: Essentials
*/
/*
* Manipulating Character Strings Using Macro Functions
* 1. Using the %INDEX Function
*/

/*
* The %INDEX function enables you to search for a substring
* within a string. If found, %INDEX returns the position
* of the first character of the substring within the string.
*
* %INDEX function syntax consists of the function name,
* with the required arguments source and string.
* Both source and string are character strings
* or expressions that can include constant text,
* macro variable references, macro functions, and macro calls.
*
* The %INDEX function searches source for the first occurrence
* of string and returns the position of its first character.
*
* If an exact match of string is not found,
* the function returns 0.
*/

%let sitelist = DALLAS SEATTLE BOSTON;


%let value = %index(&sitelist, LA);

/* Here, %INDEX searches the macro variable sitelist,


looking for the first occurrence of the string LA.
The %INDEX function finds the character string LA
in the word DALLAS, beginning at position 4.
%INDEX returns the numeric value 4.
This example demonstrates that %INDEX might return
unexpected results, such as finding character strings within words.
If you were looking for LA as an abbreviation for Los Angeles,
you'd need to revise your code.
You could use a macro quoting function.
*/

/*L2.3-Using_EVAL_Function*/

/*
* Lesson 2.3: Using the %EVAL Function
* Lesson 2 - Using Macro Functions
* SAS Macro Language 1: Essentials
*/
/*
* Using Arithmetic and Logical Expressions
* 1. Using the %EVAL Function
*/

/*
* The %EVAL function evaluates arithmetic and logical expressions. These
expressions are sequences of operators and operands, forming sets of instructions
that are evaluated to produce a result. The arguments within these expressions are
temporarily converted to numbers so that a calculation can be performed. The
results are returned as text. An arithmetic expression contains an arithmetic
operator. A logical expression contains a logical operator.
*/

/*
Let's see how we can use it, and an arithmetic expression,
to calculate a date range in our PROC MEANS step.
This PROC MEANS step summarizes the contents of the orion.order_fact data set.
The report includes the minimum, maximum, and mean values
for each of three order types during a specified date range.
The order types refer to retail store, catalog, and Internet orders respectively.
Currently, the year variables are hardcoded into both the WHERE statement
and the TITLE statement. We'd need to change each one manually
if we wanted to reuse this program for a different date range.
Let's change the year values to macro variables
and assign values based on the current date.
That way, these values will update automatically.
proc means data=orion.order_fact maxdec=2 min max mean;
class order_type;
var total_retail_price;
where year(order_date) between 2009 and 2010; // <-- dates are hardcoded
title1 "Orders for 2009 and 2010"; // <-- dates are hardcoded
title2 "(as of &sysdate9)";
run;
*/

OPTIONS SYMBOLGEN;

/*obtain the value for the current year*/


%let thisyr = %substr(&sysdate9, 6);
/*define the value of the macro variable lastyr*/
%let lastyr = %eval(&thisyr - 1);

proc means data=orion.order_fact maxdec=2 min max mean;


class order_type;
var total_retail_price;
where year(order_date) between &lastyr and &thisyr;
title1 "Orders for &lastyr and &thisyr";
title2 "(as of &sysdate9)";
run;

/*L2.3-Using_SYSEVAL_Function*/

/*
* Lesson 2.3: Using the %EVAL Function
* Lesson 2 - Using Macro Functions
* SAS Macro Language 1: Essentials
*/
/*
* Using Arithmetic and Logical Expressions
* 1. Using the %EVAL Function
*/

/*
* The %EVAL function evaluates arithmetic and logical expressions. These
expressions are sequences of operators and operands, forming sets of instructions
that are evaluated to produce a result. The arguments within these expressions are
temporarily converted to numbers so that a calculation can be performed. The
results are returned as text. An arithmetic expression contains an arithmetic
operator. A logical expression contains a logical operator.
*/

/*
Let's see how we can use it, and an arithmetic expression,
to calculate a date range in our PROC MEANS step.
This PROC MEANS step summarizes the contents of the orion.order_fact data set.
The report includes the minimum, maximum, and mean values
for each of three order types during a specified date range.
The order types refer to retail store, catalog, and Internet orders respectively.
Currently, the year variables are hardcoded into both the WHERE statement
and the TITLE statement. We'd need to change each one manually
if we wanted to reuse this program for a different date range.
Let's change the year values to macro variables
and assign values based on the current date.
That way, these values will update automatically.
proc means data=orion.order_fact maxdec=2 min max mean;
class order_type;
var total_retail_price;
where year(order_date) between 2009 and 2010; // <-- dates are hardcoded
title1 "Orders for 2009 and 2010"; // <-- dates are hardcoded
title2 "(as of &sysdate9)";
run;
*/

OPTIONS SYMBOLGEN;

/*obtain the value for the current year*/


%let thisyr = %substr(&sysdate9, 6);
/*define the value of the macro variable lastyr*/
%let lastyr = %eval(&thisyr - 1);

proc means data=orion.order_fact maxdec=2 min max mean;


class order_type;
var total_retail_price;
where year(order_date) between &lastyr and &thisyr;
title1 "Orders for &lastyr and &thisyr";
title2 "(as of &sysdate9)";
run;

/*L2.4-Using_SYSEVAL_Function*/

/*
* Lesson 2.4: Using the %SYSEVAL Function
* Lesson 2 - Using Macro Functions
* SAS Macro Language 1: Essentials
*/
/*
* Using Arithmetic and Logical Expressions
* 1. Using the %SYSEVAL Function
*/

/*
* The %SYSEVALF function evaluates arithmetic and logical expressions
* using floating-point arithmetic and returns a value
* that is formatted using the BEST32. format.
* The result of the evaluation is always text.
*
* Syntax:
* %SYSEVALF (arithmetic-or-logical-expression <, conversion-type>)
* After the keyword %SYSEVALF, you specify the arithmetic or logical expression,
* followed by an optional conversion type (BOOLEAN, CEIL, FLOOR, or INTEGER).
* These conversion types tailor the value returned by %SYSEVALF
* so that it can be used in other macro expressions
* that require integer or Boolean values.
* Be sure to choose the correct option for your data,
* in order to prevent errors or unexpected results.
*/

/*
Suppose you need to use an expression
that contains noninteger values. As you've seen,
the %EVAL function generates an error message
in the log when it encounters an expression
that contains noninteger values.
You can use the %SYSEVALF function to avoid these error messages.
*/

OPTIONS SYMBOLGEN;

%let a = 100;
%let b = 1.59;
%let y = %sysevalf(&a+&b);

%put The result with SYSEVALF is: &y;


%put BOOLEAN conversion: %sysevalf(&a +&b, boolean);
%put CEIL conversion: %sysevalf(&a +&b, ceil);
%put FLOOR conversion: %sysevalf(&a +&b, floor);
%put INTEGER conversion: %sysevalf(&a +&b, integer);

/*L2.5-Using_SYSFUNC_Function*/

/*
* Lesson 2.5: Using %SYSFUNC with SAS Functions
* Lesson 2 - Using Macro Functions
* SAS Macro Language 1: Essentials
*/
/*
* Using Arithmetic and Logical Expressions
* 1. Using the %SYSFUNC Function
*/
/*
* use %SYSFUNC to invoke the SAS function PROPCASE
* in order to display the data set name
* in proper case in the TITLE statement.
*/

/* 1. Submit this program to create a temporary version of the orders data set that
contains data values for the current year. */
options symbolgen;
%let thisyr=%substr(&sysdate9,6);
%let numyrs=%eval(&thisyr-2007);

/* Create work.orders1. */
data orders1;
set orion.orders;
drop Year StopYear;
output;
StopYear=%substr(&sysdate9,6)-1;
if Year(Order_Date)=2007;
do Year=1 to &numYrs;
Order_Date=Order_Date+365;
Delivery_Date=Delivery_Date+365;
output;
end;
run;

proc sort data=orders1;


by Order_Date Customer_ID ;
run;

options nosymbolgen;

/* 2. Copy and paste the following code into the editor. This DATA step creates a
subset of the orders data set. It includes all orders for the years 2007 through
the current year.*/

%let dsn=work.orders1;
%let var=order_date;
%let name=%scan(&dsn,2,.);
%let startyear=2007;
%let curr_year=%substr(&sysdate9,6);

data &name;
set &dsn;
where &startyear <= Year(&var) <= &curr_year;
run;

title "Listing of %scan(&syslast,2,.) Data for &startyear-&curr_year";


proc print data=&syslast;
run;

/* 3. Revise the code in order to display the data set name in proper case in the
TITLE statement. Use %SYSFUNC to invoke the SAS function PROPCASE. The PROPCASE
function converts all words in an argument to proper case. The code will now look
like this:*/
%let dsn=work.orders1;
%let var=order_date;
%let name=%scan(&dsn,2,.);
%let startyear=2007;
%let curr_year=%substr(&sysdate9,6);

data &name;
set &dsn;
where &startyear <= Year(&var) <= &curr_year;
run;

title "Listing of %sysfunc(propcase(%scan(&syslast,2, .))) Data for &startyear-


&curr_year";
proc print data=&syslast;
run;
title;

/*L3-practice1*/

/*
* Practice 1: Create a Macro Variable Using the CALL SYMPUTX Routine
* Lesson 3 - Creating Macro Variables at Execution Time
* SAS Macro Language 1: Essentials
*/
/* Task:
n this practice you create a series of reports that show the orders taken by an
employee. The SAS data set orion.orders contains order information, including the
employee ID of the employee who took the order. The SAS data set
orion.employee_addresses contains employee data, including the employee ID numbers
and names.
Reminder: Make sure you've defined the Orion library.
1. Copy and paste the following code into the editor:
title;
footnote;
%let idnum=121044;
proc print data=orion.orders noobs;
var order_ID order_type order_date delivery_date;
where employee_ID=&idnum;
title "Orders Taken by Employee &idnum";
run;
2. Submit the program and view the results.
3. Modify the program. Add a DATA step to access the orion.employee_addresses data
set and create a macro variable, Name. Assign Name the name of the employee whose
ID number matches the value of IDnum used in the report. The employee names are
stored in the Employee_Name variable in the orion.employee_addresses data set.
4. Modify the TITLE statement to display the employee's ID number followed by a
colon and the employee's name.
5. Submit the program and view the results.
6. Change the value of the ID number to 121066, and then re-submit the program and
view the results.
*/

/* 1. */

title;
footnote;

%let idnum=121044;
proc print data=orion.orders noobs;
var order_ID order_type order_date delivery_date;
where employee_ID=&idnum;
title "Orders Taken by Employee &idnum";
run;

/* 3. */
%let idnum = 121044;

data _null_;
set orion.employee_addresses;
where employee_ID = &idnum;
call symputx ('name', employee_name);
run;

proc print data=orion.orders noobs;


var order_ID order_type order_date delivery_date;
where employee_ID = &idnum;
title "Orders Taken by Employee &idnum";
run;

/* 4. */
%let idnum = 121044;

data _null_;
set orion.employee_addresses;
where employee_ID = &idnum;
call symputx ('name',employee_name);
run;

proc print data=orion.orders noobs;


var order_ID order_type order_date delivery_date;
where employee_ID = &idnum;
title "Orders Taken by Employee &idnum: &name";
run;

/* 6. */
%let idnum = 121066;
data _null_;
set orion.employee_addresses;
where employee_ID = &idnum;
call symputx ('name',employee_name);
run;

proc print data=orion.orders noobs;


var order_ID order_type order_date delivery_date;
where employee_ID= &idnum;
title "Orders Taken by Employee &idnum: &name";
run;

/*L3-practice2*/

/*
* Practice 2: Create Macro Variables Using the CALL SYMPUTX Routine
* Lesson 3 - Creating Macro Variables at Execution Time
* SAS Macro Language 1: Essentials
*/
/* Task:
In this practice, you use the SAS data set orion.order_fact to create a temporary,
summary data set. You use the data in the summary data set to create a macro
variable that stores the customer ID number of the top customer. Then you use that
macro variable to look up the customer's name. Customer names are stored in the SAS
data set orion.customer_dim.
Reminder: Make sure you've defined the Orion library.
1. Submit the following program. This program creates a summary data set named
Customer_Sum that summarizes Total_Retail_Price by Customer_ID and sorts the data
set by descending CustTotalPurchase.
title;
footnote;
proc means data=orion.order_fact sum nway noprint;
var total_retail_price;
class customer_ID;
output out=customer_sum sum=CustTotalPurchase;
run;
proc sort data=customer_sum ;
by descending CustTotalPurchase;
run;
2. Read the temporary data set, Customer_Sum and create a macro variable named Top
that contains the ID number for the top customer. Hint: Remember that the first
observation in the Customer_Sum data set represents the top customer.
3. Add a PROC PRINT step as follows:
Suppress the OBS column.
Print only the orders for the top customer in orion.orders.
Include only the variables Order_ID, Order_Type, Order_Date, and Delivery_Date.
Add a TITLE statement that references the Top macro variable. For example, the
title might read Orders for Customer 16.
4. Submit the program and view the results.
5. Modify the program. The data set orion.customer_dim contains customer names. Add
a DATA step to access orion.customer_dim and create a macro variable, Name. Assign
Name the name of the top customer. Then reference Name in the TITLE statement to
print the customer's name instead of the customer's ID.
6. Submit the program and view the results.
*/

/* 1.*/
title;
footnote;

proc means data=orion.order_fact sum nway noprint;


var total_retail_price;
class customer_ID;
output out=customer_sum sum=CustTotalPurchase;
run;

proc sort data=customer_sum ;


by descending CustTotalPurchase;
run;

/* 2.*/
data _null_;
set customer_sum (obs=1);
call symputx('top', customer_ID);
run;

/* 3.*/
proc print data=orion.orders noobs;
where customer_ID = &top;
var order_ID order_type order_date delivery_date;
title "Orders for Customer &top";
run;

/* 5.*/
data _null_;
set customer_sum (obs=1);
call symputx('top', customer_ID);
run;

data _null_;
set orion.customer_dim;
where customer_ID = &top;
call symputx('topname', customer_name);
run;

proc print data=orion.orders noobs;


where customer_ID = &top;
var order_ID order_type order_date delivery_date;
title "Orders for Customer &topname";
run;

/*L3-practice3*/

/*
* Practice 3: Creating a Series of Macro Variables
* Lesson 3 - Creating Macro Variables at Execution Time
* SAS Macro Language 1: Essentials
*/
/* Task:
The SAS data set orion.customer contains a variable named Customer_Type_ID which
identifies each customer's membership level and activity level. The
orion.customer_type data set contains the Customer_Type_ID variable as well as a
variable named Customer_Type. The Customer_Type variable contains a description of
the membership level and the activity level. Modify the code shown below to create
a series of macro variables named Typexxxx, where xxxx is the value of
Customer_Type_ID.
Reminder: Make sure you've defined the Orion library.
1. Copy and paste the following code into the editor:
title;
footnote;
%let id=1020;
proc print data=orion.customer;
var Customer_Name Customer_ID Gender;
where customer_type_id=&id;
title "A list of &id";
run;
2. Submit the code and view the results.
3. Modify the code. Add a data step to access orion.customer_type and create a
series of macro variables, Typexxxx, where xxxx represents the values of
Customer_Type_ID. Assign the corresponding value of Customer_Type to each Typexxxx
macro variable.
4. Modify the TITLE statement so that it displays a description of the customer
type. Use an indirect macro variable reference to one of the TYPE variables based
in the current value of ID. Submit the program and verify that the title contains a
description instead of a Customer_Type_ID.
5. Change the value of the ID to 2030, and then resubmit the program and view the
results.
*/

/* 1.*/
title;
footnote;

%let id=1020;
proc print data=orion.customer;
var Customer_Name Customer_ID Gender;
where customer_type_id=&id;
title "A list of &id";
run;

/* 3.*/
%let id=1020;

data _null_;
set orion.customer_type;
call symputx('type'||left(customer_type_id),customer_type);
/*Alternative solution using the CATS function*/
/*call symputx(cats('type',customer_type_id),customer_type);*/
run;

proc print data=orion.customer;


var Customer_Name Customer_ID Gender;
where customer_type_id=&id;
title "A list of &id";
run;

/* 4.*/
%let id=1020;

data _null_;
set orion.customer_type;
call symputx('type'||left(customer_type_id),customer_type);
/*Alternative solution using the CATS function*/
/*call symputx(cats('type',customer_type_id),customer_type);*/
run;

proc print data=orion.customer;


var Customer_Name Customer_ID Gender;
where customer_type_id=&id;
title "A list of &&type&id";
run;

/* 5.*/
%let id=2030;

data _null_;
set orion.customer_type;
call symputx('type'||left(customer_type_id),customer_type);
/* alternative solution using the CATS function*/
/* call symputx(cats('type',customer_type_id),customer_type);*/
run;

proc print data=orion.customer;


var Customer_Name Customer_ID Gender;
where customer_type_id=&id;
title "A list of &&type&id";
run;

/*L3-practice4*/

/*
* Practice 4: Create Macro Variables Using PROC SQL
* Lesson 3 - Creating Macro Variables at Execution Time
* SAS Macro Language 1: Essentials
*/
/* Task:
The program below includes a PROC MEANS step, a DATA step, and a PROC PRINT step.
The PROC MEANS step uses the data in orion.order_fact to calculate the average
quantity and average total retail price for orders placed in January 2011. The DATA
step creates the macro variables Quant (which stores the value of the average
quantity) and Price (which stores the value of the average price). The PROC PRINT
step references Quant and Price in the TITLE statements. In this practice, you
replace the PROC MEANS step and the DATA step with a single PROC SQL step.
Reminder: Make sure you've defined the Orion library.
1. Copy and paste the following code into the editor:
title;
footnote;
%let start=01Jan2011;
%let stop=31Jan2011;
proc means data=orion.order_fact noprint;
where order_date between "&start"d and "&stop"d;
var Quantity Total_Retail_Price;
output out=stats_q_p mean=Avg_Quant Avg_Price;
run;
data _null_;
set stats_q_p;
call symputx('Quant',put(Avg_Quant,4.2));
call symputx('Price',put(Avg_Price,dollar7.2));
run;
proc print data=orion.order_fact noobs n;
where order_date between "&start"d and "&stop"d;
var Order_ID Order_Date Quantity Total_Retail_Price;
sum Quantity Total_Retail_Price;
format Total_Retail_Price dollar6.;
title1 "Report from &start to &stop";
title3 "Average Quantity: &quant";
title4 "Average Price: &price";
run;
2. Submit the program and view the results.
3. Delete the macro variables Quant and Price from the Global Symbol Table.
4. Replace the PROC MEANS step and the DATA step with a PROC SQL step that creates
the macro variables Quant and Price. Be sure to use the same subsetting criteria
and formats as the PROC MEANS step and the DATA step.
5. Submit the modified program and verify the results are the same.
*/

/* 1.*/
title;
footnote;

%let start=01Jan2011;
%let stop=31Jan2011;

proc means data=orion.order_fact noprint;


where order_date between "&start"d and "&stop"d;
var Quantity Total_Retail_Price;
output out=stats_q_p mean=Avg_Quant Avg_Price;
run;

data _null_;
set stats_q_p;
call symputx('Quant',put(Avg_Quant,4.2));
call symputx('Price',put(Avg_Price,dollar7.2));
run;

proc print data=orion.order_fact noobs n;


where order_date between "&start"d and "&stop"d;
var Order_ID Order_Date Quantity Total_Retail_Price;
sum Quantity Total_Retail_Price;
format Total_Retail_Price dollar6.;
title1 "Report from &start to &stop";
title3 "Average Quantity: &quant";
title4 "Average Price: &price";
run;

/*L3.1-SalesReport-FirstAttempt*/

/*
* Lesson 3.1: Sales Report - First Attempt
* Lesson 2 - Creating Macro Variables at Execution Time
* SAS Macro Language 1: Essentials
*/
/*
* Creating a Macro Variable during DATA Step Execution
*/

%let month=2;
%let year=2011;

data orders1;
keep Order_Date Order_Type Quantity Total_Retail_Price;
set orion.order_fact end=final;
where year(Order_Date)=&year and month(Order_Date)=&month;
if Order_Type=3 then Number+1;
if final then do;
put Number=;
if Number=0 then do;
%let foot=No Internet Orders;
end;
else do;
%let foot=Some Internet Orders;
end;
end;
run;

proc print data=orders1;


title "Orders for &month-&year";
footnote "&foot";
run;

title;
footnote;

/*L3.10-Creating_a_Series_of_Macro-Variables_Using_PROC-SQL*/

/*
* Lesson 3.10: Creating a Series of Macro Variables Using PROC SQL
* Lesson 3 - Creating Macro Variables at Execution Time
* SAS Macro Language 1: Essentials
*/
/*
* Creating or update Macro Variables during SQL Step Execution
* - Creating a Series of Macro Variables Using PROC SQL
*/

/*
You can use the INTO clause
to create one new macro variable
for each row in the result of the SELECT statement. */

title 'Top 2011 Sales';


proc sql outobs=3;
select total_retail_price
/*only one column is selected, Total_Retail_Price*/
into :price1-:price3
/*creates three macro variables: price1 through price3*/

/*This is a series of macro variables, which is similar


to the name series you saw earlier.

In order to identify the top sales, the results


are sorted in descending order by Total_Retail_Price,
so the highest orders will appear first in the output.

PROC SQL output shows column labels by default.


So, Total_Retail_Price is labeled Total Retail Price for This Product.

Because you only want the top three, there is no need to keep
the other output values. The OUTOBS=3 option limits the output
to three rows and gives you the top three sales. */

from orion.order_fact
where year(order_date)=2011
order by total_retail_price desc;
quit;

/*
* Lesson 3.11: Creating an Additional Series of Macro Variables Using PROC SQL
* Lesson 3 - Creating Macro Variables at Execution Time
* SAS Macro Language 1: Essentials
*/
/*
* Creating or update Macro Variables during SQL Step Execution
* - Creating a Series of Macro Variables Using PROC SQL
* - Creating an Additional Series of Macro Variables Using PROC SQL
*/

/*
Modify the previous program to store the top three sales in 2011
and the dates on which the sales occurred.
T
o do that, you need to include two columns in the SELECT statement list:
Total_Retail_Price and Order_Date.
Order_Date is formatted as a calendar date in the form mm/dd/yyyy.
The INTO clause names two series of macro variables:
price1 through price3
and
date1 through date3.
Let's look at the output and see how the values are assigned to the macro
variables.
The output consists of three rows and two columns.
The assignment is positional, so the first value in the first row is assigned to
price1.
The second value in the first row is assigned to date1.
The values from row two are stored in price2 and date2.
The values from row three are stored in price3 and date3.
*/

title 'Top 2011 Sales';


proc sql outobs=3;
select total_retail_price, Order_Date format=mmddyy10.
into :price1-:price3, :date1-:date3
from orion.order_fact
where year(order_date)=2011
order by total_retail_price desc;
quit;

/*L3.11-Creating_an_Additional_Series_of_Macro_Variables_Using_PROC-SQL*/

/*
* Lesson 3.11: Creating an Additional Series of Macro Variables Using PROC SQL
* Lesson 3 - Creating Macro Variables at Execution Time
* SAS Macro Language 1: Essentials
*/
/*
* Creating or update Macro Variables during SQL Step Execution
* - Creating a Series of Macro Variables Using PROC SQL
* - Creating an Additional Series of Macro Variables Using PROC SQL
*/

/*
Modify the previous program to store the top three sales in 2011
and the dates on which the sales occurred.
T
o do that, you need to include two columns in the SELECT statement list:
Total_Retail_Price and Order_Date.
Order_Date is formatted as a calendar date in the form mm/dd/yyyy.
The INTO clause names two series of macro variables:
price1 through price3
and
date1 through date3.
Let's look at the output and see how the values are assigned to the macro
variables.
The output consists of three rows and two columns.
The assignment is positional, so the first value in the first row is assigned to
price1.
The second value in the first row is assigned to date1.
The values from row two are stored in price2 and date2.
The values from row three are stored in price3 and date3.
*/

title 'Top 2011 Sales';


proc sql outobs=3;
select total_retail_price, Order_Date format=mmddyy10.
into :price1-:price3, :date1-:date3
from orion.order_fact
where year(order_date)=2011
order by total_retail_price desc;
quit;

/*L3.12-Creating_Macro-Variables_during_PROC-SQL_Step_Execution*/

/*
* Lesson 3.12: Creating Macro Variables during PROC SQL Step Execution
* Lesson 3 - Creating Macro Variables at Execution Time
* SAS Macro Language 1: Essentials
*/

/*
* Creating or update Macro Variables during SQL Step Execution
* - Creating a Series of Macro Variables Using PROC SQL
* - Creating an Additional Series of Macro Variables Using PROC SQL
*
* Because of its ability to summarize data and create macro variables in a single
step,
* PROC SQL made this program shorter and simpler.
*/

/*
* Program to identify exceptional customers for a given year.
* Exceptional customers were defined as those who ordered
* more units or units of higher retail value than the average customer.
*/

/*
*
* initial program version
*
*/
%let year=2011;

/*The PROC MEANS step analyzes orion.order_fact. It selects orders for the
requested year, calculates the average Quantity and price for all selected
orders, and writes these statistics to a temporary data set, stats. The
variables are named AvgQty and AvgPrice respectively.
*/
proc means data=orion.order_fact noprint;
where year(Order_Date) = &year;
var Quantity Total_Retail_Price;
output out=stats mean=AvgQty AvgPrice;
run;

/*The DATA _NULL_ step reads the temporary data set, stats, created by PROC
MEANS. The SYMPUTX routine uses the values of AvgQty and AvgPrice to create
two macro variables, qty and price.
*/
data _null_;
set stats;
call symputx('qty', round(AvgQTY, .01));
call symputx('price', round(AvgPrice, .01));
run;

/*These macro variables are used in the TITLE and FOOTNOTE statements.
They're also used in the PROC PRINT step to select the observations
in which the Quantity is greater than the average Quantity
and the total retail price is greater than the average retail price.
*/
title "Orders Exceeding Average in &year";
footnote "Average Quantity: &qty";
footnote2 "Average Price: &price";

proc print data=orion.order_fact noobs;


where year(Order_Date) = &year and Quantity > &qty
and Total_Retail_Price > &price;
var Customer_ID order_id Order_Date Quantity Total_Retail_Price;
run;

title;
footnote;

/*
*
* Modify the program as shown here:
*
*/

%let year=2011;

/*use a single PROC SQL query to replace


the PROC MEANS step and the DATA step.*/
proc sql noprint;
/*We're using this PROC SQL step to calculate averages and create macro variables,
but not to display a report. So, let's add a NOPRINT option.*/

/*select two columns from the order_fact table*/


/*use a summary function to calculate the average for each file*/
select avg(Quantity), avg(Total_Retail_Price)
/*use an INTO clause to assign these values to the macro variables*/
into :qty, :price
from orion.order_fact
where year(Order_Date)=&year;
run;

/* add a couple of %LET statements to remove leading blanks from quantity and
price*/
%let qty=&qty;
%let price=&price;

/*reference the macro variables in the TITLE and FOOTNOTE statements*/


title "Orders Exceeding Average in &year";
footnote "Average Quantity: &qty";
footnote2 "Average Price: &price";

/* reference the macro variables in the PROC PRINT step


to select the correct observations */
proc print data=orion.order_fact noobs;
where year(Order_Date)=&year and Quantity>&qty
and Total_Retail_Price>&price;
var Customer_ID order_id Order_Date Quantity Total_Retail_Price;
run;

title;
footnote;

/*L3.13-Storing_a_List_of_Values_in_a_Macro-Variable*/

/*
* Lesson 3.13: Storing a List of Values in a Macro Variable
* Lesson 3 - Creating Macro Variables at Execution Time
* SAS Macro Language 1: Essentials
*/

/*
* Creating or update Macro Variables during SQL Step Execution
* - Storing a List of Values in a Macro Variable
*/

/*
* Sometimes it's convenient to store a list of values in a macro variable.
*
* Suppose you were asked to create a macro variable, countries,
* to store the unique values of the countries found in orion.customer.
* The country codes are to be separated by a comma and a space.
*
* You can use an alternate form of the INTO clause in order to
* take all of the values of a column (variable)
* and concatenate them into the value of one macro variable.
*
* The INTO clause names the macro variable to be created.
* The SEPARATED BY clause specifies the character or characters
* that will be used as a delimiter in the value of the macro variable.
*
* Notice that the delimiter is enclosed in quotation marks.
* The DISTINCT keyword isn't required, but it eliminates duplicates
* by selecting unique values of the selected column.
*
* After you execute the PROC SQL step, you can use the %PUT statement
* to write the value of countries to the log.
*/

PROC SQL noprint;


SELECT DISTINCT country
INTO :countries
SEPARATED BY ', '
FROM orion.customer;
QUIT;

%PUT &countries;

/*L3.2-Using-CALL-SYMPUTX-Routine*/

/*
* Lesson 3.2: Using the CALL SYMPUTX Routine
* Lesson 2 - Creating Macro Variables at Execution Time
* SAS Macro Language 1: Essentials
*/
/*
* Creating a Macro Variable during DATA Step Execution
* - Using the CALL SYMPUTX Routine
*/

%let month=2;
%let year=2011;

data orders2;
keep Order_Date Order_Type Quantity Total_Retail_Price;
set orion.order_fact end=final;
where year(Order_Date)=&year and month(Order_Date)=&month;
if Order_Type=3 then Number+1;
if final then do;
put Number=;
/* replace the %LET statements within the conditional DO groups
with calls to the SYMPUTX routine*/
if Number=0 then do;
/* %let foot=No Internet Orders; */
call symputx('foot', 'No Internet Orders');
end;
else do;
/* %let foot=Some Internet Orders; */
call symputx('foot', 'Some Internet Orders');
end;
end;
run;

proc print data=orders2;


title "Orders for &month-&year";
footnote "&foot";
run;

title;
footnote;

/*L3.3-Using-CALL-SYMPUTX_with_DATA_StepVariable*/

/*
* Lesson 3.3: Using SYMPUTX with a DATA Step Variable
* Lesson 2 - Creating Macro Variables at Execution Time
* SAS Macro Language 1: Essentials
*/
/*
* Creating a Macro Variable during DATA Step Execution
* - Using the CALL SYMPUTX Routine
* - Using SYMPUTX with a DATA Step Variable
*/

/*The Sales manager wants to see the data for January.


So, change the value of the macro variable month to 1.*/
%let month=1;
%let year=2011;

data orders2;
keep Order_Date Order_Type Quantity Total_Retail_Price;
set orion.order_fact end=final;
where year(Order_Date)=&year and month(Order_Date)=&month;

/* If the value of Order_Type is 3 increment the value of Number by 1 */


if Order_Type=3 then Number+1;
/* The footnote needs to include the number of Internet orders
placed during the reporting period.
Because you don't need conditional logic,
remove the IF-THEN/ELSE statements. */

/*use SYMPUTX routine to assign the value of Number to the &num (macro variable)
*/
IF final THEN CALL symputx('num', Number);

/* During the last iteration of the DATA step, SAS calls the SYMPUTX routine
in order to create the macro variable num.
The first argument to SYMPUTX, the character constant, num,
is the name of the macro variable.
The second argument is the DATA step variable, Number.

The SYMPUTX routine assigns the value of Number to the macro variable, num.
Because Number is a numeric variable and macro variables store text values,
SYMPUTX automatically converts the value of Number to character,
using the BEST32. format.
*/

run;

proc print data=orders2;


title "Orders for &month-&year";
footnote "&num Internet Orders";
run;

title;
footnote;

/*L3.4-Using-CALL-SYMPUTX_with_DATA_Step_Expression*/

/*
* Lesson 3.5: Passing Data between Steps
* Lesson 3 - Creating Macro Variables at Execution Time
* SAS Macro Language 1: Essentials
*/
/*
* Creating a Macro Variable during DATA Step Execution
* - Using the CALL SYMPUTX Routine
* - Using SYMPUTX with a DATA Step Variable
* - Using SYMPUTX with a DATA Step Expression
* - Passing Data between Steps
*/

%let year=2009;

/* STEP 1*/
/* The PROC MEANS step analyzes orion.order_fact.
It selects orders for the requested year,
calculates the average quantity and price
for all selected orders,
and writes these statistics to a temporary data set, stats.
The variables are named AvgQty and AvgPrice respectively.
*/
proc means data=orion.order_fact noprint;
/*For this task, you don't need a PROC MEANS report.
To suppress the report use the NOPRINT option.*/

/*subsets the order_fact data set*/


where year(Order_Date) = &year;
/*specify variables to be analyzed*/
var Quantity Total_Retail_Price;
/*use OUTPUT to create an output data set called stats in the work library */
output out=stats mean=AvgQty AvgPrice;
/*MEAN= option renames the mean statistic for each analyzed variable.
The names are assigned by position.
The mean statistic for the first variable in the VAR statement, Quantity,
is stored using the first name listed in the MEAN= option, AvgQty.
The mean statistic for the second variable in the VAR statement,
Total_Retail_Price,
is stored using the second name listed in the MEAN= option, AvgPrice.*/
run;

/* STEP 2*/

/* The DATA _NULL_ step reads the temporary data set, stats,
created by PROC MEANS.
The SYMPUTX routine uses the values of AvgQty and AvgPrice
to create two macro variables, Qty and Price.
AS THAY CAN NOT BE CREATED IN the MEAN Step.
*/
data _null_;
/* Usually, the DATA statement specifies at least one data set name
that SAS uses to create an output data set.
Using the keyword _NULL_ as the data set name
causes SAS to execute the DATA step
without writing observations to a data set. */

/* In this case, you simply need the DATA step


to create the macro variables using the SYMPUTX routine.*/

/* Can you use the SYMPUTX routine in a PROC step?


No, CALL routines are only valid in a DATA step.
This DATA step reads the temporary data set,
Stats, which contains one observation. */

set stats;
/* A call to the SYMPUTX routine creates the macro variable qty
and assigns it the value of AvgQty from the stats data set.*/
call symputx('qty', round(AvgQTY, .01));
/*SYMPUTX routine creates the macro variable price
and assigns it the value of AvgPrice from stats data set.*/
call symputx('price', round(AvgPrice, .01));
run;

/* STEP 3*/
/* use macro variables - &qty and &price*/
title "Orders Exceeding Average in &year";
footnote "Average Quantity: &qty";
footnote2 "Average Price: &price";

proc print data=orion.order_fact noobs;


where year(Order_Date)=&year and Quantity>&qty
and Total_Retail_Price>&price;
var Customer_ID order_id Order_Date Quantity Total_Retail_Price;
run;

title;
footnote;

/*L3.5-Using-CALL-SYMPUTX_with_DATA_Step_Expression*/

/*
* Lesson 3.5: Passing Data between Steps
* Lesson 3 - Creating Macro Variables at Execution Time
* SAS Macro Language 1: Essentials
*/
/*
* Creating a Macro Variable during DATA Step Execution
* - Using the CALL SYMPUTX Routine
* - Using SYMPUTX with a DATA Step Variable
* - Using SYMPUTX with a DATA Step Expression
* - Passing Data between Steps
*/

%let year=2009;

/* STEP 1*/
/* The PROC MEANS step analyzes orion.order_fact.
It selects orders for the requested year,
calculates the average quantity and price
for all selected orders,
and writes these statistics to a temporary data set, stats.
The variables are named AvgQty and AvgPrice respectively.
*/
proc means data=orion.order_fact noprint;
/*For this task, you don't need a PROC MEANS report.
To suppress the report use the NOPRINT option.*/
/*subsets the order_fact data set*/
where year(Order_Date) = &year;
/*specify variables to be analyzed*/
var Quantity Total_Retail_Price;
/*use OUTPUT to create an output data set called stats in the work library */
output out=stats mean=AvgQty AvgPrice;
/*MEAN= option renames the mean statistic for each analyzed variable.
The names are assigned by position.
The mean statistic for the first variable in the VAR statement, Quantity,
is stored using the first name listed in the MEAN= option, AvgQty.
The mean statistic for the second variable in the VAR statement,
Total_Retail_Price,
is stored using the second name listed in the MEAN= option, AvgPrice.*/
run;

/* STEP 2*/

/* The DATA _NULL_ step reads the temporary data set, stats,
created by PROC MEANS.
The SYMPUTX routine uses the values of AvgQty and AvgPrice
to create two macro variables, Qty and Price.
AS THAY CAN NOT BE CREATED IN the MEAN Step.
*/
data _null_;
/* Usually, the DATA statement specifies at least one data set name
that SAS uses to create an output data set.
Using the keyword _NULL_ as the data set name
causes SAS to execute the DATA step
without writing observations to a data set. */

/* In this case, you simply need the DATA step


to create the macro variables using the SYMPUTX routine.*/

/* Can you use the SYMPUTX routine in a PROC step?


No, CALL routines are only valid in a DATA step.
This DATA step reads the temporary data set,
Stats, which contains one observation. */

set stats;
/* A call to the SYMPUTX routine creates the macro variable qty
and assigns it the value of AvgQty from the stats data set.*/
call symputx('qty', round(AvgQTY, .01));
/*SYMPUTX routine creates the macro variable price
and assigns it the value of AvgPrice from stats data set.*/
call symputx('price', round(AvgPrice, .01));
run;

/* STEP 3*/
/* use macro variables - &qty and &price*/
title "Orders Exceeding Average in &year";
footnote "Average Quantity: &qty";
footnote2 "Average Price: &price";

proc print data=orion.order_fact noobs;


where year(Order_Date)=&year and Quantity>&qty
and Total_Retail_Price>&price;
var Customer_ID order_id Order_Date Quantity Total_Retail_Price;
run;
title;
footnote;

/*L3.5-Using-CALL-SYMPUTX_with_PassingDat_between_Steps*/

/*
* Lesson 3.5: Passing Data between Steps
* Lesson 3 - Creating Macro Variables at Execution Time
* SAS Macro Language 1: Essentials
*/
/*
* Creating a Macro Variable during DATA Step Execution
* - Using the CALL SYMPUTX Routine
* - Using SYMPUTX with a DATA Step Variable
* - Using SYMPUTX with a DATA Step Expression
* - Passing Data between Steps
*/

%let year=2009;

/* STEP 1*/
/* The PROC MEANS step analyzes orion.order_fact.
It selects orders for the requested year,
calculates the average quantity and price
for all selected orders,
and writes these statistics to a temporary data set, stats.
The variables are named AvgQty and AvgPrice respectively.
*/
proc means data=orion.order_fact noprint;
/*For this task, you don't need a PROC MEANS report.
To suppress the report use the NOPRINT option.*/

/*subsets the order_fact data set*/


where year(Order_Date) = &year;
/*specify variables to be analyzed*/
var Quantity Total_Retail_Price;
/*use OUTPUT to create an output data set called stats in the work library */
output out=stats mean=AvgQty AvgPrice;
/*MEAN= option renames the mean statistic for each analyzed variable.
The names are assigned by position.
The mean statistic for the first variable in the VAR statement, Quantity,
is stored using the first name listed in the MEAN= option, AvgQty.
The mean statistic for the second variable in the VAR statement,
Total_Retail_Price,
is stored using the second name listed in the MEAN= option, AvgPrice.*/
run;

/* STEP 2*/

/* The DATA _NULL_ step reads the temporary data set, stats,
created by PROC MEANS.
The SYMPUTX routine uses the values of AvgQty and AvgPrice
to create two macro variables, Qty and Price.
AS THAY CAN NOT BE CREATED IN the MEAN Step.
*/
data _null_;
/* Usually, the DATA statement specifies at least one data set name
that SAS uses to create an output data set.
Using the keyword _NULL_ as the data set name
causes SAS to execute the DATA step
without writing observations to a data set. */

/* In this case, you simply need the DATA step


to create the macro variables using the SYMPUTX routine.*/

/* Can you use the SYMPUTX routine in a PROC step?


No, CALL routines are only valid in a DATA step.
This DATA step reads the temporary data set,
Stats, which contains one observation. */

set stats;
/* A call to the SYMPUTX routine creates the macro variable qty
and assigns it the value of AvgQty from the stats data set.*/
call symputx('qty', round(AvgQTY, .01));
/*SYMPUTX routine creates the macro variable price
and assigns it the value of AvgPrice from stats data set.*/
call symputx('price', round(AvgPrice, .01));
run;

/* STEP 3*/
/* use macro variables - &qty and &price*/
title "Orders Exceeding Average in &year";
footnote "Average Quantity: &qty";
footnote2 "Average Price: &price";

proc print data=orion.order_fact noobs;


where year(Order_Date)=&year and Quantity>&qty
and Total_Retail_Price>&price;
var Customer_ID order_id Order_Date Quantity Total_Retail_Price;
run;

title;
footnote;

/*L3.6-Using_Table-Lookup-Application_to_Create_Macro-Variables*/

/*
* Lesson 3.6: Using a Table Lookup Application to Create Macro Variables
* Lesson 3 - Creating Macro Variables at Execution Time
* SAS Macro Language 1: Essentials
*/
/*
* Creating a Macro Variable during DATA Step Execution
* - Using a Table Lookup Application to Create Macro Variables */

/* this program works, but it's extremely inefficient */

%let custid=9;

/*The DATA _NULL_ step uses a WHERE statement


to read the observation from orion.customer
that matches the customer ID that's stored in
the macro variable custid.
After the WHERE statement reads the observation,
the program calls the SYMPUTX routine
to create the macro variable - &name,
and assigns it the value of the DATA step variable 'Customer_Name'.
*/
data _null_;
set orion.customer;
where Customer_ID=&custid;
call symputx('name', Customer_Name);
run;

/*The PROC PRINT step uses the macro variables


custid and name in the TITLE statements.
*/
proc print data=orion.order_fact;
where Customer_ID=&custid;
var Order_Date Order_Type Quantity Total_Retail_Price;
title1 "Customer Number: &custid";
title2 "Customer Name: &name";
run;

title;

/*L3.7-Creating_a_Series_of_Macro-Variables*/

/*
* Lesson 3.7: Creating a Series of Macro Variables
* Lesson 3 - Creating Macro Variables at Execution Time
* SAS Macro Language 1: Essentials
*/
/*
* Creating a Macro Variable during DATA Step Execution
* - Creating a Series of Macro Variables
*/

/*
To make the program more efficient, you need to create
a series of macro variables, each with a unique name.
Here's an idea. We know that each customer has a unique ID.
Instead of using consecutive numbers, we can use
the value of customer_ID as the suffix.
To do that, you can call the SYMPUTX routine
with DATA step expressions for both arguments.
The first expression evaluates to a character value
that is a valid macro variable name.
This value needs to change each time
that you want to create another macro variable.
The second expression is the value
that you want to assign to the macro variable.
A common approach is to append a unique value
to a base name during each iteration of the DATA step.
For example, you might decide to use name as the base
and create a macro variable named
name1 on the first iteration,
name2 on the second iteration,
name3 on the third iteration, and so on.
To create the customer report, you can append
the value of the Customer_ID variable to the base, name.
For example, Cornelia Krahl�s customer number is 9,
so when her observation is being processed in the DATA step,
you can create the macro variable name9
and assign it the value Cornelia Krahl.
*/

data _null_;
set orion.customer;
/* concatenate the value of Customer_ID (a DATA step variable)
onto a base string 'name' to create macro var */
/*call symputx('name'||left(Customer_ID)), Customer_Name);*/
call symputx(cats('name',Customer_ID), Customer_Name);
run;

%put _user_;

%let custid=9;
proc print data=orion.order_fact;
where Customer_ID=&custid;
var Order_Date Order_Type Quantity Total_Retail_Price;
title1 "Customer Number: &custid";
title2 "Customer Name: &name9";
run;

title;

/*L3.8-Using_an_Indirect_Reference*/

/*
* Lesson 3.8: Using an Indirect Reference
* Lesson 3 - Creating Macro Variables at Execution Time
* SAS Macro Language 1: Essentials
*/
/*
* Creating a Macro Variable during DATA Step Execution
* - Creating a Series of Macro Variables
* - Using an Indirect Reference
*/

/*
To obtain the correct output, the macro processor must
resolve &custid before &name.
Because the value of the custid macro variable matches
part of the name of a name macro variable,
the custid macro variable can indirectly reference
a name macro variable.
To create an indirect reference, you need to precede
a name token with multiple ampersands (&&....).
By preceding a macro variable reference with two ampersands,
you delay the resolution of the reference until the second scan.
When the macro processor encounters two ampersands,
it resolves them to one ampersand
and continues to rescan from left to right,
from the point where the multiple ampersands begin.
This action is known as the Forward Rescan Rule.
*/

data _null_;
set orion.customer;
call symputx(cats('name',Customer_ID), Customer_Name);
run;

%let custid=9;

proc print data=orion.order_fact;


where Customer_ID=&custid;
var Order_Date Order_Type Quantity Total_Retail_Price;
title1 "Customer Number: &custid";

/*use the Forward Rescan Rule*/


title2 "Customer Name: &&name&custid";
/*On the first scan, the macro processor
resolves the two ampersands to one ampersand.
The text name is unchanged.
The scan continues and &custid resolves to 9.
Because we started with multiple ampersands,
the Forward Rescan Rule is in effect
and a second scan occurs: &name9 resolves to Cornelia Krahl.

At this point, scanning is complete because there are


no remaining macro variable references.*/
run;

title;

/*According to the Forward Rescan Rule, you need to use


three ampersands in front of a macro variable name
when its value exactly matches the name
of a second macro variable.
The need for more than three ampersands is extremely rare.
*/

/*L3.9-Using_PROC_SQL*/

/*
* Lesson 3.9: Using PROC SQL
* Lesson 3 - Creating Macro Variables at Execution Time
* SAS Macro Language 1: Essentials
*/
/*
* Creating or update Macro Variables during SQL Step Execution
*/

/*
Remember, in PROC SQL, the SELECT statement
is used to generate a report
by selecting one or more columns from a table.
The resulting report includes the selected columns
and all the rows from the selected table.
The INTO clause in a SELECT statement enables you
to create or update macro variables.
The values of the selected columns
are assigned to the new macro variables.
The INTO clause begins with the keyword INTO
and is followed by a colon and then the name
of the macro variable to be created.
If more than one macro variable is listed,
they must be comma-separated and each must start with a colon.
The colon doesn't become part of the name.
If you don't include the colon, an error message
is written to the log.
*/

proc sql noprint;


/*use the NOPRINT option to suppress the report*/
select sum(total_retail_price) format=dollar8.
/*create macro variable '&total' */
into :total
from orion.order_fact
where year(order_date)=2011 and order_type=3;
quit;

/*use %LET statement to remove any leading


or trailing blanks that are stored in the value*/
%let total=&total;
%put Total 2011 Internet Sales: &total;

title 'Top 2011 Sales';


proc sql outobs=3;
select total_retail_price, Order_Date format=mmddyy10.
into :price1-:price3,:date1-:date3
from orion.order_fact
where year(order_date)=2011
order by total_retail_price desc;
quit;

/*L4-pract1-Defining_and_Calling_a_Macro*/

/*
* Practice 1: Defining and Calling a Macro
* Lesson 4 - Creating and Using Macro Programs
* SAS Macro Language 1: Essentials
*/
/* 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.
1. Copy and paste the following code into the editor:
title "&type Customers";
proc print data=orion.customer_dim;
var Customer_Name Customer_Gender Customer_Age;
where Customer_Group contains "&type";
run;
title;
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.
3. Submit a %LET statement to assign the value Gold to the macro variable Type.
Call the macro, examine the log and view the results.
4. Change the value of Type to Internet.
5. 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.
*/

/* 1.*/
title "&type Customers";
proc print data=orion.customer_dim;
var Customer_Name Customer_Gender Customer_Age;
where Customer_Group contains "&type";
run;
title;

/* 2.*/
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;

/* 3.*/
%let type=Gold;
%Customers

/* 4.*/
%let type=Internet;
%Customers

/* 5.*/
options mprint;
%Customers

/*L4-pract2-Calling_Macro_from_TITLE_Statement*/

/*
* Practice 2: Calling a Macro from a TITLE Statement
* Lesson 4 - Creating and Using Macro Programs
* SAS Macro Language 1: Essentials
*/
/* 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.
1. Define a macro that calls the SAS function, TIME, and displays it in the
TIMEAMPM. format. Name the macro Currtime. Submit the macro definition.
2. Copy and paste the following code into the editor.
title 'Customer List';
proc print data=orion.customer_dim(obs=10);
var Customer_Name Customer_Group;
run;
title;
3. Add a TITLE2 statement. Call the macro Currtime from the TITLE2 statement.
Submit the program and examine the results.
4. Enable the MPRINT option, resubmit the code, and view the results. Are any
messages generated by MPRINT? Why or why not?
*/

/* 1.*/
%macro Currtime;
%sysfunc(time(), TIMEAMPM.)
%mend;

/* 2. , 3. , 4.*/
options mprint;

title 'Customer List';


title2 "%currtime"; /*use "..."*/
proc print data=orion.customer_dim(obs=10);
var Customer_Name Customer_Group;
run;
title;

/*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.*/

/*L4-pract3-Defining_and_Using_Macro_Parameters*/

/*
* Practice 3: Defining and Using Macro Parameters
* Lesson 4 - Creating and Using Macro Programs
* SAS Macro Language 1: Essentials
*/
/* 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.
1. 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;
2. 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.
3. Set the MPRINT option. Call the macro defined in the previous step with a value
of Gold for the parameter and view the results.
4. all the macro again, but with a parameter value of Catalog and view the results.
5. Change the positional parameter to a keyword parameter with a default value of
Club. Submit the revised macro definition to compile the macro.
6. Call the macro defined in the previous step with a value of Internet for the
keyword parameter and view the results.
7. Call the macro again, but allow the macro to use its default parameter value.
View the results.
*/

/* 1.*/
%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;

/* 2.*/
options mcompilenote=all;
%macro customers(type);
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;

/* 3.*/
options mprint;
%customers(Gold)

/* 4.*/
%customers(Catalog)

/* 5.*/
%macro customers(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;

/* 6. */
%customers(type=Internet)

/* 7. */
%customers()
/*or just %customers*/

/*L4-pract4-Defining_and_Using_Macro_Mixed_Parameters*/

/*
* Practice 4: Defining and Using Macro Parameters
* Lesson 4 - Creating and Using Macro Programs
* SAS Macro Language 1: Essentials
*/
/* 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.
1. 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;
2. 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
3. Execute the macro using the default parameter values. View the results.
4. Call the macro again, using the appropriate parameter values to produce this
report.
5. Call the macro again, but override only the default parameter values for
statistics and decimal places to produce this this report.
*/

/* 1.*/
options nolabel;
title 'Order Stats';
proc means data=orion.order_fact maxdec=2 mean;
var total_retail_price;
class order_type;
run;
title;

/* 2.*/
options mcompilenote=all;
%macro customers(type);
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;
/* 3.*/
options mprint;
%customers(Gold)

/* 4.*/
%customers(Catalog)

/* 5.*/
%macro customers(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;

/* 6. */
%customers(type=Internet)

/* 7. */
%customers()

/*or just %customers*/

/*L4.1-Define_a_Macro*/

/*
* Lesson 4.1: Define a Macro
* Lesson 4 - Creating and Using Macro Programs
*/

/*
* Creating and Using Macro Programs
* - Define a Macro
*/

/*
A macro definition is the container that holds a macro program.
You begin a macro definition with a %MACRO statement
and end it with a %MEND statement.
You are not required to include the macro name in the %MEND statement.
But if you do, be sure that the two macro names match.
The text in your macro definition can include constant text, SAS data set names,
SAS variable names, and SAS statements.
The text can also include macro variables, macro functions, macro program
statements,
and any combination of the above.
Each macro that you define has a distinct name.
Choose a name that indicates what the macro does and follow standard SAS naming
conventions.
Avoid SAS language keywords or CALL routine names, as well as words
that are reserved by the SAS macro facility.
*/
/*
Let's return to the macro program that you need to create
that will print the most recently created data set.
Remember, to define a macro, you begin with the %MACRO statement
and indicate the name of the macro.
Let's name the macro Prtlast.
The text in this macro will consist of a PROC PRINT step.
Following the keyword, PROC PRINT, you need to specify the data set name.
Here's a question. What automatic macro variable can you use to specify
the most recently created data set?
The automatic macro variable SYSLAST stores the name of the most recently
created data set. Let's use &SYSLAST to provide the data set name
in our PROC PRINT statement. In addition to specifying the PROC PRINT and RUN
statements,
you can include any other additional SAS statements that are needed.
In this example, let's specify the number of observations and a TITLE statement.
You end the definition of the macro Prtlast with a %MEND statement.
*/

%macro prtlast;
proc print data=&syslast (obs=10);
title "Listing of &syslast data set";
run;
%mend;

/*L4.2-Compiling_a_Macro*/

/*
* Lesson 4.2: Compiling a Macro
* Lesson 4 - Creating and Using Macro Programs
*/

/*
* Creating and Using Macro Programs
* - Compiling a Macro
* -- Using the MCOMPILENOTE= Option
*/

/*
The next step in creating and using a macro is to compile it by submitting the
code. When you submit the code, the word scanner divides the macro into tokens and
sends the tokens to the macro processor for compilation. The macro processor checks
the macro language statements for syntax errors. Non-macro language statements are
not checked until the macro is executed. If the macro processor does find syntax
errors in the macro language statements, it writes any error messages to the SAS
log and creates a dummy, non-executable macro. If the macro processor does not find
any macro-level syntax errors, it compiles the macro.
The macro processor stores the compiled macro definition in a SAS catalog entry. By
default, the macro definition is stored in a catalog named work.sasmacr. In some
versions of SAS Studio the macro processor stores the compiled macro definition in
work.sasmac1, not work.sasmacr. For more information about work.sasmacr, click the
information button. Macros that are stored in this temporary SAS catalog are known
as session-compiled macros. Session-compiled macros are available for execution
during the SAS session in which they're compiled. SAS deletes the temporary catalog
that stores the macros at the end of the session. There are methods of storing
macros permanently, but these are beyond the scope of this lesson. You can consult
the SAS Help and Documentation to explore macro storage methods.
*/
/*
When you submit your macro definition to be compiled,
you might be left wondering if it compiled successfully.
By default, SAS does not display any indication
that a macro has completed compilation.
There is a system option, MCOMPILENOTE=, that can notify you.
MCOMPILENOTE=NONE is the default and specifies
that no notes are issued to the log.
When the value is set to ALL, the MCOMPILENOTE= option
issues a note to the SAS log.
The note confirms that the compilation of the macro was completed.
It also indicates the number of instructions contained in the macro and its size.
Be aware, though, that a macro can successfully compile,
but the non-macro statements can still contain errors that will cause
the macro not to execute as you intended.
*/

options mcompilenote = all;

%macro prtlast;
proc print data=&syslast (obs=10);
title "Listing of &syslast data set";
run;
%mend;

/*L4.3-Submitting_a_Macro_Definition*/

/*
* Lesson 4.3: Submitting a Macro Definition
* Lesson 4 - Creating and Using Macro Programs
*/

/*
* Creating and Using Macro Programs
* - Submitting a Macro Definition
*/

/*
In this demonstration, you submit a macro definition
and view the temporary catalog work.sasmacr.
(Remember that if you are working in SAS Studio,
your macro definitions might be stored
in the temporary catalog work.sasmac1 instead.)
Reminder: Make sure you've defined the Orion library
to the location of your practice files. For more information,
see the Setting Up for Practices section.
*/

options mcompilenote=all;

%macro puttime;
%put The current time is %sysfunc(time(),timeampm.).;
%mend puttime;

/*
Now let's check the log.
The log indicates that the macro Puttime
completed compilation without errors.
This macro is now available for use at any time during this SAS session.
*/

/*
* Let's check that our macro has been stored as expected
* in the temporary catalog work.sasmac1.
*/

/*
To see a list of temporary macros, we use the PROC CATALOG step.
We specify the keyword, PROC CATALOG,
followed by the name of the catalog
and then a CONTENTS statement.
Let's also include a title for our report.
*/

proc catalog cat=work.sasmac1;


contents;
title "My Temporary Macros";
quit;

title;

/*
It shows the macro name - Puttime,
as well as the type - macro,
and the date and time when it was created.
*/

/*L4.4-Calling_a_Macro*/

/*
* Lesson 4.4: Calling a Macro
* Lesson 4 - Creating and Using Macro Programs
*/

/*
* Calling a Macro
*/

/*
The final step in creating and using a macro is to call it.
After you compile a macro, it's available
for the duration of your SAS session.
Just as you reference macro variables in order
to access them in your code, you must call a macro program
in order to execute it in your SAS program.
To call, or invoke, a macro, precede the name of the macro
with a percent sign (%).

The call can be made anywhere in a program, except


within the data lines of a DATA Step statement.
The macro call requires no semicolon, because it is not a SAS statement.
The macro call causes the macro to execute.
*/
/*
For example, to use the Puttime macro you saw in the last demonstration,
you simply submit the code %puttime.
Because the Puttime macro includes a %PUT statement,
SAS will write a note to the log that indicates the current time.
*/

%puttime

/*
Log:
...
94 %puttime
The current time is 1:03:15 PM.
*/

/*L4.5-Calling_a_Macro_in_a_SAS_Program*/

/*
* Lesson 4.5: Calling a Macro in a SAS Program
* Lesson 4 - Creating and Using Macro Programs
*/

/*
* Compiling and calling a Macro in a SAS Program
*/

/*
In this demonstration, you compile and call the Prtlast macro.
Prtlast stores a PROC PRINT step that prints
the most recently created data set.
Reminder: Make sure you've defined the Orion library
to the location of your practice files.
For more information, see the Setting Up for Practices section.
Note: If you're using SAS Enterprise Guide to complete this course,
you set up your practice files in the Orion library
in the same physical location as the Work library.
Be sure to use the data set name customers in order to ensure
that you do not overwrite the practice file customer.
*/

options mcompilenote = all;

%macro prtlast;
proc print data=&syslast (obs=10);
title "Listing of &syslast";
run;

title;
%mend;

/*
Now that the Prtlast macro has been compiled,
we can use it for the duration of this SAS session,
without needing to resubmit the macro definition.
Let's create two new data sets.
Create the first data set, work.customers
by selecting the Customer_ID, Country, and Customer_Name variables
from the orion.customer data set.
Create a second data set, work.sort_customers
by sorting work.customers by the variable Country.
Call the Prtlast macro after each of these DATA and PROC steps.
*/
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

/*
Log:
...
69 %prtlast
NOTE: There were 10 observations read from the data set WORK.SORT_CUSTOMERS.
NOTE: PROCEDURE PRINT used (Total process time):
*/

/*
Notice that you see a note from PROC PRINT, but not the PROC PRINT code itself,
because the call to the macro does not display the text that is sent to the
compiler.
*/

/*L4.6-Macro_Execution_and_the_MPRINT_Option*/

/*
* Lesson 4.6: Macro Execution and the MPRINT Option
* Lesson 4 - Creating and Using Macro Programs
*/

/*
* Macro Execution and the MPRINT Option
*/

/*
n this demonstration, you call the Prtlast macro
with the MPRINT option enabled.
Prtlast stores a PROC PRINT step that prints a data set
defined by the macro variable dsn.
The macro variable vars assigns the variables
that will be included in the output.
Reminder: Make sure you've defined the Orion library to the location of your
practice files. For more information, see the Setting Up for Practices section.
*/

/* 1. compile the macro*/


%macro prtlast;
proc print data=&dsn;
var &vars;
run;

title;
%mend;

/* 2. assign values to dsn and vars*/


%let dsn=orion.city;
%let vars=City_Name Country;

/* 3.set the MPRINT option*/


options mprint;
/*MPRINT option writes to the log the text that is sent to the compiler.*/
%prtlast

/*
Log:
...
66 %prtlast
MPRINT(PRTLAST): proc print data=orion.city;
MPRINT(PRTLAST): var City_Name Country;
MPRINT(PRTLAST): run;
*/
/*
The log indicates that SAS ran the PROC PRINT step stored
in the Prtlast macro as expected.
Because you specified the MPRINT option,
SAS wrote the PROC PRINT code itself to the log.
Notice that the macro variable references for dsn and vars
are resolved in the MPRINT messages.
*/

/*L4.7-Defining_and_Calling_Macro_with_Positiona_Parameters*/

/*
* Lesson 4.7: Defining and Calling a Macro with Positional Parameters
* Lesson 4 - Creating and Using Macro Programs
*/

/*
* Defining and Calling a Macro with Positional Parameters
*/

/*
In this demonstration, you define and call another macro program with positional
parameters.
The macro program Count invokes a PROC FREQ step in which the order date
will be between the start date and the stop date.
The start and stop dates are defined by the macro variables start and stop.
The program also includes a 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.
Reminder: Make sure you've defined the Orion library to the location of your
practice files.
For more information, see the Setting Up for Practices section.
*/

%macro count;
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;

title;
%mend count;
/*
If you used this macro program as is, you'd need to specify
the values for these three macro variables using
three %LET statements each time that you call the program.
You'll use positional parameters to make the code more concise.
Revise the code so that the Count macro
specifies three parameters - opts, start, and stop,
in the %MACRO statement.
*/
options mcompilenote=all

%macro count(opts, start, stop); /*positional parameters*/


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;

title;
%mend count;

/*
Now call the Count macro and assign values to the macro variables
that you created by using a parameter list.
Be sure that you turn on the MPRINT option
so that you can verify the values of the macro variables.
First, call the Count macro and assign
the value nocum to the macro variable opts,
01jan11 to the macro variable start,
and 31dec11 to stop.
Ensure that the order of the parameters here matches that in the macro definition.
*/
options mprint;
%count(nocum, 01jan11, 31dec11)

/*The first macro call successfully executed the frequency procedure


with the NOCUM option - suppressing the cumulative frequencies and percentages.*/

/*
Create a second macro call in which you assign opts a null value.
*/
options mprint;
%count(, 01jul11, 31dec11)
/*The second macro call included all FREQ statistics.*/

/*L4.8-Defining_and_Calling_Macro_with_Keyword_Parameters*/
/*
* Lesson 4.8: Defining and Calling a Macro with Keyword Parameters
* Lesson 4 - Creating and Using Macro Programs
*/

/*
* Defining and Calling a Macro with Keyword Parameters
*/

/*
In this demonstration, you use keyword parameters
to assign macro variable values for the Count macro.
Reminder: Make sure you've defined the Orion library to the location of your
practice files.
For more information, see the Setting Up for Practices section.
*/

%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;

title;
%mend count;

/*
Specify three keyword parameters in the %MACRO statement: opts, start, and stop.
Assign a default value of null to the macro variable opts.
Assign default values of 01jan11 to the macro variable start and 31dec11 to stop.
*/
%macro count(opts=,start=01jan11,stop=31dec11);
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;

title;
%mend count;

/*
Create three calls to the Count macro.
Turn on the MPRINT option so that you can verify the values of the macro variables.
In the first call, use default values for the parameters.
In the second call, assign the value nocum to the macro variable opts.
Use the default values for the macro variables start and stop
by simply omitting those keywords from the macro call.
For the third call, specify a new stop date of 01jul11
and specify both nocum and nopercent for the macro variable opts.
Remember, when you call a macro with keyword parameters, the parameters can be in
any order.
*/
options mprint;
%count()
%count(opts=nocum)
%count(stop=01jul11, opts=nocum nopercent)

/*L4.9-Defining_and_Calling_Macro_with_Mixed_Parameters*/

/*
* Lesson 4.9: Using a Combination of Positional and Keyword Parameters
* Lesson 4 - Creating and Using Macro Programs
*/

/*
* Using a Combination of Positional and Keyword Parameters
*/

/*
In this demonstration, you use both positional and keyword parameters
to assign macro variable values for the Count macro.
Reminder: Make sure you've defined the orion library to the location of your
practice files.
For more information, see the Setting Up for Practices section.
*/

%macro count(opts=,start=01jan11,stop=31dec11);
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;

title;
%mend count;

/*
The statistics options that you need to specify could be different
every time that you call this macro.
Therefore, revise the code to use a positional parameter for the macro variable
opts.
For the macro variables start and stop, the date range needed might stay consistent

for a set of reports. Therefore, leave these keyword parameters with the default
values shown.
*/
%macro count(opts,start=01jan11,stop=31dec11);
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;

title;
%mend count;

/*
Create four calls to the Count macro.
Turn on the MPRINT option so that you can verify the values of the macro variables.
In the first call, use default values for the parameters.
In the second call, assign the value nocum to the macro variable opts.
Use the default values for the macro variables start and stop
by simply omitting those keywords from the macro call.
For the third call, specify a new stop date of 30jun11
and a new start date of 01apr11.
Remember that when you call a macro with keyword parameters,
the parameters can be in any order.
This time, assign opts a null value by omitting it from the call.
For the fourth call, you'll use both positional and keyword parameters.
Remember to specify the positional parameters first.
Specify both nocum and nopercent for the macro variable opts.
Next, assign the stop macro variable the value 30jun11
and omit the start macro variable in order to ensure
that this call to the macro uses the default value for this item.
*/
options mprint;
%count()
%count(nocum)
%count(stop=30jun11, start=01apr11)
%count(nocum nopercent, stop=30jun11)

/*
The second macro call successfully assigns the nocum value
and suppresses the cumulative statistics columns.
The third macro call successfully assigns a new value of 30jun11
to the macro variable stop and 01apr11 to the macro variable start.
The fourth call successfully suppresses both
the cumulative frequency and percent columns
and assigns a new value of 30jun11 to the macro variable stop.
*/

Вам также может понравиться