11 Chapter 4: Developing Reusable Macros 4.1 Introduction 4.2 Developing Macro Routines 4.3 Developing Macro Functions.

Slides:



Advertisements
Similar presentations
CC SQL Utilities.
Advertisements

Examples from SAS Functions by Example Ron Cody
Chapter 9: Introducing Macro Variables 1 © Spring 2012 Imelda Go, John Grego, Jennifer Lasecki and the University of South Carolina.
Chapter 3: Editing and Debugging SAS Programs. Some useful tips of using Program Editor Add line number: In the Command Box, type num, enter. Save SAS.
Chapter 11: Creating and Using Macro Programs 1 STAT 541 ©Spring 2012 Imelda Go, John Grego, Jennifer Lasecki and the University of South Carolina.
 2006 Pearson Education, Inc. All rights reserved Introduction to Classes and Objects.
VBA Modules, Functions, Variables, and Constants
 2000 Deitel & Associates, Inc. All rights reserved. Chapter 17 - The Preprocessor Outline 17.1Introduction 17.2The #include Preprocessor Directive 17.3The.
 2006 Pearson Education, Inc. All rights reserved Introduction to Classes and Objects.
ASP.NET Programming with C# and SQL Server First Edition
 2000 Prentice Hall, Inc. All rights reserved. Chapter 13 - The Preprocessor Outline 13.1Introduction 13.2The #include Preprocessor Directive 13.3The.
Chapter 18: Modifying SAS Data Sets and Tracking Changes 1 STAT 541 ©Spring 2012 Imelda Go, John Grego, Jennifer Lasecki and the University of South Carolina.
Understanding SAS Data Step Processing Alan C. Elliott stattutorials.com.
Creating SAS® Data Sets
 2007 Pearson Education, Inc. All rights reserved C Preprocessor.
“SAS macros are just text substitution!” “ARRRRGGHHH!!!”
I OWA S TATE U NIVERSITY Department of Animal Science Writing Flexible Codes with the SAS Macro Facility (Chapter in the 7 Little SAS Book) Animal Science.
1 Chapter 3: Macro Definitions 3.1 Defining and Calling a Macro 3.2 Macro Parameters 3.3 Macro Storage (Self-Study)
11 Chapter 2: Working with Data in a Project 2.1 Introduction to Tabular Data 2.2 Accessing Local Data 2.3 Importing Text Files 2.4 Editing Tables in the.
Chapter 10:Processing Macro Variables at Execution Time 1 STAT 541 © Spring 2012 Imelda Go, John Grego, Jennifer Lasecki and the University of South Carolina.
1 Chapter 5: Creating Summarized Output 5.1 Generating Summary Statistics 5.2 Creating a Summary Report with the Summary Tables Task 5.3 Creating and Applying.
1 Chapter 4: Creating Simple Queries 4.1 Introduction to Querying Data 4.2 Filtering and Sorting Data 4.3 Creating New Columns with an Expression 4.4 Grouping.
1 Chapter 5: Macro Programs 5.1 Conditional Processing 5.2 Parameter Validation 5.3 Iterative Processing 5.4 Global and Local Symbol Tables.
11 Chapter 3: Reading and Processing Data 3.1 Processing SAS Data Sets 3.2 Processing External Files.
1 Chapter 1: Introduction 1.1 Course Logistics 1.2 Purpose of the Macro Facility 1.3 Program Flow.
C++ for Engineers and Scientists Second Edition Chapter 6 Modularity Using Functions.
Introduction to SAS. What is SAS? SAS originally stood for “Statistical Analysis System”. SAS is a computer software system that provides all the tools.
© Copyright 1992–2004 by Deitel & Associates, Inc. and Pearson Education Inc. All Rights Reserved. C How To Program - 4th edition Deitels Class 05 University.
SAS Macro: Some Tips for Debugging Stat St. Paul’s Hospital April 2, 2007.
INTRODUCTION TO SAS MACRO PROCESSING James R. Bence, Ph.D., Co-Director Quantitative Fisheries Center Professor Department of Fisheries and Wildlife March.
SAS Efficiency Techniques and Methods By Kelley Weston Sr. Statistical Programmer Quintiles.
Chapter 06 (Part I) Functions and an Introduction to Recursion.
5/30/2010 SAS Macro Language Group 6 Pradnya Nimkar, Li Lin, Linsong Zhang & Loc Tran.
SQL Chapter Two. Overview Basic Structure Verifying Statements Specifying Columns Specifying Rows.
Fundamentals of C and C++ Programming. EEL 3801 – Lotzi Bölöni Sub-Topics  Basic Program Structure  Variables - Types and Declarations  Basic Program.
Introduction to SAS Macros Center for Statistical Consulting Short Course April 15, 2004.
BMTRY 789 Lecture 11: Debugging Readings – Chapter 10 (3 rd Ed) from “The Little SAS Book” Lab Problems – None Homework Due – None Final Project Presentations.
1 Chapter 4: DATA Step and SQL Interfaces 4.1 Creating Macro Variables in the DATA Step 4.2 Indirect References to Macro Variables 4.3 Retrieving Macro.
Chapter 17: Formatting Data 1 STAT 541 ©Spring 2012 Imelda Go, John Grego, Jennifer Lasecki and the University of South Carolina.
1 Chapter 7: Customizing and Organizing Project Results 7.1 Combining Results 7.2 Updating Results 7.3 Customizing the Output Style (Self-Study)
Summer SAS Workshop Lecture 3. Summer SAS Workshop Website
 2003 Prentice Hall, Inc. All rights reserved. 1 IS 0020 Program Design and Software Tools Preprocessor Midterm Review Lecture 7 Feb 17, 2004.
Chapter 7: Macros in SAS  Macros provide for more flexible programming in SAS  Macros make SAS more “object-oriented”, like R 1 © Fall 2011 John Grego.
FOR MONDAY: Be prepared to hand in a one-page summary of the data you are going to use for your project and your questions to be addressed in the project.
SAS for Data Management and Analysis
 2000 Prentice Hall, Inc. All rights reserved. Chapter 13 - The Preprocessor Outline 13.1Introduction 13.2The #include Preprocessor Directive 13.3The.
1 Checking Data with the PRINT and FREQ Procedures.
SAS ® 101 Based on Learning SAS by Example: A Programmer’s Guide Chapter 25 By Tasha Chapman, Oregon Health Authority.
1 Cleaning Invalid Data. Clean data by using assignment statements in the DATA step. Clean data by using IF-THEN / ELSE statements in the DATA step. 2.
Copyright 2009 The Little Engine That Could: Using EXCEL LIBNAME Engine Options to Enhance Data Transfers between SAS® and Microsoft® Excel Files William.
FILES AND EXCEPTIONS Topics Introduction to File Input and Output Using Loops to Process Files Processing Records Exceptions.
Better Metadata Through SAS® II: %SYSFUNC, PROC DATASETS, and Dictionary Tables.
SAS ® 101 Based on Learning SAS by Example: A Programmer’s Guide Chapters 5 & 6 By Ravi Mandal.
BIL 104E Introduction to Scientific and Engineering Computing Lecture 4.
Chapter 5: Passing and Processing Macro Parameters
Chapter 6: Set Operators
SQL and SQL*Plus Interaction
C++ for Engineers and Scientists Second Edition
3 Macro Storage.
ISC440: Web Programming 2 Server-side Scripting PHP 3
Conditional Processing
Chapter 7: Macros in SAS Macros provide for more flexible programming in SAS Macros make SAS more “object-oriented”, like R Not a strong suit of text ©
Topics Introduction to File Input and Output
Creating Macro Variables in the DATA Step
Macro Variable’s scope
PHP.
Retrieving Macro Variables in the DATA Step
3 Iterative Processing.
3 Parameter Validation.
Topics Introduction to File Input and Output
Presentation transcript:

11 Chapter 4: Developing Reusable Macros 4.1 Introduction 4.2 Developing Macro Routines 4.3 Developing Macro Functions

22 Chapter 4: Developing Reusable Macros 4.1 Introduction 4.2 Developing Macro Routines 4.3 Developing Macro Functions

3 Objectives 3 Describe the difference between a routine and a function. Modify the SASAUTOS= system option.

4 Creating Reusable Macros To adhere to Orion Star best practices, the programmers want to implement common tasks through reusable macro programs. A library of reusable macros aid in these tasks: simplifying macro definitions hiding complex code sharing and reusing code 4

5 Is It a Function or a Routine? Reusable macros can be divided into two categories, user-defined functions and user-defined routines. Each is created and implemented differently. 5 User-Defined FunctionsUser-Defined Routines are macros that contain only macro code. are macros that use DATA and PROC step code along with macro code. return a single value.can return multiple values. are called “in-line” within other statements such as %LET, %IF, or traditional SAS code. are not called “in-line” and can be treated as macro steps.

6 Steps for Creating Reusable Macros These steps are used to create reusable macros: 1.Thoroughly test and debug the macro. 2.Save the macro as an autocall macro. 3.Set the SASAUTOS= system option to specify the directory for the autocall library. 4.Call the utility macro in a subsequent macro. 6

7 Incorrectly Adding a Custom Autocall Library 7 Before you modify the SASAUTOS= option, it is important to review the current values to not overwrite current settings. The default action of the SASAUTOS= system option is to replace the current search list. This is the incorrect way to add an autocall library. proc options option=sasautos; run; options sasautos=('s:\workshop'); proc options option=sasautos; run;

8 Incorrectly Adding a Custom Autocall Library 8 Partial SAS Log The autocall macros supplied by SAS along with those in s:\orion_autocall are no longer available in the current session. 59 proc options option=sasautos; 60 run; SASAUTOS=('s:\orion_autocall', sasautos) Search list for autocall macros 61 options sasautos=('s:\workshop'); 62 proc options option=sasautos; 63 run; SASAUTOS=('s:\workshop') Search list for autocall macros

9 Adding a Custom Autocall Library 9 The correct way to add an autocall library is to append it to the current search list. Partial SAS Log 94 options sasautos=('s:\workshop' 's:\orion_autocall' sasautos); proc options option=sasautos; 97 run; SASAUTOS=('s:\workshop' 's:\orion_autocall' sasautos) Search list for autocall macros

10 Chapter 4: Developing Reusable Macros 4.1 Introduction 4.2 Developing Macro Routines 4.3 Developing Macro Functions

11 Objectives 11 Create user-defined macro routines. Control when macro variables are created.

12 User-Defined Macro Routines After assessing their needs, the Orion Star programmers decided to create macro routines to perform the following tasks: delete global macro variables convert local macro variable values to uppercase create a list of character values create a list of data set names 12

13 Deleting Global Macro Variables 13 The DELVARS autocall macro will delete all global macro variables. delvars %macro delvars; data temp; set sashelp.vmacro; where scope='GLOBAL'; run; data _null_; set temp; call symdel(name); run; %mend delvars;

14 Uppercasing Local Macro Variable Values 14 The Orion Star programmers want to replace the multiple %LET statements with a macro routine to uppercase all local macro variable values. %macro printlst(country=AU,gender=F,type=CLUB); %let country=%upcase(&country); %let gender=%upcase(&gender); %let type=%upcase(&type); proc print data=orion.customer_dim; var Customer_Name Customer_ID Customer_Age_Group Customer_Type; where Customer_Country = "&country" and Customer_Gender = "&gender" and upcase(Customer_Type) contains "&type"; title "Listing of Customer Names Subsetted By:"; title2 "Country=&country Gender=&gender Customer Type=&type"; run; %mend printlst; %printlst(country=ca,gender=m,type=med)

15 Uppercasing Local Macro Variable Values 15 Using available metadata, the UPVALUE autocall macro will uppercase all local macro variable values. %macro upvalue; data _null_; set sashelp.vmacro; where scope not in ('GLOBAL', 'AUTOMATIC'); call symputx(name,upcase(value)); run; %mend upvalue; upvalue

16 Uppercasing Local Macro Variable Values 16 The UPVALUE autocall macro is used by the PRINTLST macro to convert all parameter values to uppercase. %macro printlst(country=AU,gender=F,type=CLUB); %upvalue proc print data=orion.customer_dim; var Customer_Name Customer_ID Customer_Age_Group Customer_Type; where Customer_Country = "&country" and Customer_Gender = "&gender" and upcase(Customer_Type) contains "&type"; title "Listing of Customer Names Subsetted By:"; title2 "Country=&country Gender=&gender Customer Type=&type"; run; %mend printlst; %printlst(country=ca,gender=m,type=med) m204d01

17 Uppercasing Local Macro Variable Values 17 Partial SAS Log 83 %printlst(country=ca,gender=m,type=med) NOTE: There were 3 observations read from the data set SASHELP.VMACRO. WHERE scope not in ('AUTOMATIC', 'GLOBAL'); NOTE: DATA statement used (Total process time): real time 0.01 seconds cpu time 0.03 seconds NOTE: There were 3 observations read from the data set ORION.CUSTOMER_DIM. WHERE (Customer_Country='CA') and (Customer_Gender='M') and UPCASE(Customer_Type) contains 'MED'; m204d01

18 Generating a Dynamic List of Values 18 With data constantly changing, the Orion Star programmers find that they spend time maintaining a valid list of values for the IN operator. %macro baddata(dsn); %upvalue proc print data=&dsn; where Customer_Country not in ("AU" "CA" "DE" "IL" "TR" "US" "ZA"); title "Observations with Invalid Customer_Country Values"; run; title; %mend baddata;

19 Generating a Dynamic List of Values 19 The CHARLIST autocall macro was created to generate a macro variable whose value is a quoted, data-dependent list. charlist %macro charlist(lookupdsn, lookupvar); %local j; data _null_; set &lookupdsn end=final; call symputx(cats("&lookupvar",_n_), quote(&lookupvar),'L'); if final=1 then call symputx('n', _n_,'L'); run; %do j= 1 %to &n; %let clist=&clist &&&lookupvar&j; %end; %mend charlist;

20 Generating a Dynamic List of Values 20 charlist %macro charlist(lookupdsn, lookupvar); %local j; data _null_; set &lookupdsn end=final; call symputx(cats("&lookupvar",_n_), quote(&lookupvar),'L'); if final=1 then call symputx('n', _n_,'L'); run; %do j= 1 %to &n; %let clist=&clist &&&lookupvar&j; %end; %mend charlist; The DATA step generates the following macro variables: CUSTOMER_COUNTRY1 "AU" CUSTOMER_COUNTRY2 "CA" CUSTOMER_COUNTRY3 "DE" CUSTOMER_ COUNTRY4 "IL" CUSTOMER_ COUNTRY5 "TR" CUSTOMER_ COUNTRY6 "US" CUSTOMER_ COUNTRY7 "ZA" N 7

21 Generating a Dynamic List of Values 21 charlist %macro charlist(lookupdsn, lookupvar); %local j; data _null_; set &lookupdsn end=final; call symputx(cats("&lookupvar",_n_), quote(&lookupvar),'L'); if final=1 then call symputx('n', _n_,'L'); run; %do j= 1 %to &n; %let clist=&clist &&&lookupvar&j; %end; %mend charlist; The %DO loop generates the following macro variable: CLIST "AU" "CA" "DE" "IL" "TR" "US" "ZA"

22 Three ampersands are required when the value of one macro variable matches the entire name of a second macro variable. Partial Symbol Table 22 Triple Ampersand Resolution reference 1st scan &&&lookupvar&j &customer_country1 "AU" 2nd scan VariableValue J1 LOOKUPVARCustomer _Country CUSTOMER_COUNTRY1"AU" CUSTOMER_COUNTRY2"CA"

23

Quiz 1.Open the program m204a01. 2.Replace the question marks with a macro call to the CHARLIST autocall macro to create the macro variable CLIST. 24 m204a01 %macro baddata(dsn,lookupdsn,lookupvar); %local clist; ??????? %upvalue proc print data=&dsn; where &lookupvar not in(&clist); title "Observations with Invalid &lookupvar Values"; run; title; %mend baddata; %baddata(orion.invalid_customer_dim, orion.country_lookup, customer_country)

Quiz – Correct Answer 1.Open the program m204a01. 2.Replace the question marks with a macro call to the CHARLIST autocall macro to create the macro variable CLIST. 25 m204a01 %macro baddata(dsn,lookupdsn,lookupvar); %local clist; %charlist(&lookupdsn,&lookupvar) %upvalue proc print data=&dsn; where &lookupvar not in(&clist); title "Observations with Invalid &lookupvar Values"; run; title; %mend baddata; %baddata(orion.invalid_customer_dim, orion.country_lookup, customer_country)

Quiz i – Log %baddata(orion.invalid_customer_dim,orion.country_lookup, customer_country) NOTE: There were 7 observations read from the data set ORION.COUNTRY_LOOKUP. NOTE: There were 4 observations read from the data set SASHELP.VMACRO. WHERE scope not in ('AUTOMATIC', 'GLOBAL'); NOTE: There were 5 observations read from the data set ORION.INVALID_CUSTOMER_DIM. WHERE CUSTOMER_COUNTRY not in ('AU', 'CA', 'DE', 'IL', 'TR', 'US', 'ZA'); m204a01

Quiz i – Output 27 m204a01 Observations with Invalid CUSTOMER_COUNTRY Values Customer_ Customer_ Customer_ Customer_ Customer_ Customer_ Obs Customer_ID Country Gender Customer_Name FirstName LastName BirthDate Age_Group 4 10 UZ F Karen Ballinger Karen Ballinger 18OCT years 7 13 DR M Markus Sepke Markus Sepke 21JUL years ZZ M Michael Dineley Michael Dineley 17APR years TT M Selim Okay Selim Okay 14OCT years II M Avinoam Zweig Avinoam Zweig 28SEP years Customer_ Obs Customer_Type Customer_Group Age 4 Orion Club members high activity Orion Club members 23 7 Orion Club Gold members low activity Orion Club Gold members Orion Club members medium activity Orion Club members Orion Club members low activity Orion Club members Orion Club members high activity Orion Club members 48

28 Testing the Existence of a Macro Variable 28 When macro applications need to share or reuse macro variables, it is best to create them once in the global symbol table instead of rebuilding them in every application. The %SYMEXIST function first searches any local symbol tables and then searches the global symbol table for the macro variable. General form of the %SYMEXIST function: The %SYMEXIST function returns a value of 1 if the macro variable is found or a 0 if it is not found. %SYMEXIST(macro-variable-name)

29 Generating Macro Variables when Needed This demonstration illustrates conditionally executing the DSNLIST autocall macro in the PRINTALL and BACKUP macros. 29 m204d02

30 Exercise This exercise reinforces the concepts discussed previously. 30

31 Chapter 4: Developing Reusable Macros 4.1 Introduction 4.2 Developing Macro Routines 4.3 Developing Macro Functions

32 Objectives 32 Implement DATA step function equivalents as macros. Implement operators not supported by the macro facility.

33 User-Defined Macro Functions To simplify coding, the Orion Star programmers want to define macros that will act as macro functions to perform the following tasks: return the current date check the existence of a data set validate whether a string is a valid SAS name extract a data set attribute calculate the age of a data set 33

34 User-Defined Macro Functions 1. Define a macro with the same name as the DATA step function, if possible. 2. Create macro parameters that mirror the function arguments. In addition, you can modify how the macro interprets its arguments to customize its behavior. 3. Invoke the DATA step function using %SYSFUNC. 4. Save the macro as an autocall macro. 5. Call the macro the same way as a macro function. 34 Use these five steps to create a macro equivalent for a DATA step function:

35 Macro Version of the TODAY Function Create a macro version of the TODAY function, and format the results with the DATE9. format. 35 today %macro today; %sysfunc(today(), date9.) %mend today; Notice the lack of a semicolon.

36 Macro Version of the TODAY Function The Orion Star programmers will use the TODAY autocall macro to append today’s date to the end of a data set name. 36 %macro bckdsn(dsn); %local memname rename; %let dsn=%upcase(&dsn); %let memname=%scan(&dsn,-1,.); %let rename=%sysfunc(rename(&dsn,&memname._%today)); proc import datafile= "s:\workshop\c4\&memname" out=&dsn dbms=excel replace; mixed=yes; run; proc sql; select libname, memname from dictionary.tables where libname="%scan(&dsn,1,.)" and memname like "&memname%"; quit; %mend bckdsn; m204d03

37 Macro Version of the TODAY Function Partial SAS Log PROC SQL Output 37 Library Name Member Name ƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒ ORION DAILY_SALES ORION DAILY_SALES_02NOV %bckdsn(orion.daily_sales) MLOGIC(BCKDSN): Beginning execution. MLOGIC(BCKDSN): Parameter DSN has value orion.daily_sales MLOGIC(BCKDSN): %LOCAL MEMNAME RENAME MLOGIC(BCKDSN): %LET (variable name is DSN) MLOGIC(BCKDSN): %LET (variable name is MEMNAME) MLOGIC(BCKDSN): %LET (variable name is RENAME) MLOGIC(TODAY): Beginning execution. MLOGIC(TODAY): Ending execution. m204d03

38 Determining Data Set Existence Whenever a data set name is passed as a parameter value, the Orion Star programmers want to test for the existence of the data set before progressing further in a macro program. They created a macro version of the EXIST function to simplify the macro program. 38 %macro exist(dsn); %sysfunc(exist(&dsn)) %mend exist; exist

39 Using the EXIST Autocall Macro This demonstration illustrates using the EXIST autocall macro to determine whether a data set exists. 39 m204d04

40 Validating SAS Names Many of Orion Star’s applications import data from an external file and use the filename as the data set name. The programmers found that the filename is not always a valid SAS name. The macro version of the NVALID function determines if the value of PARAM is a valid SAS name. The NVALID function returns a value of 1 if the string is a valid SAS name or 0 if it is not a valid name. 40 nvalid %macro nvalid(param); %sysfunc(nvalid(&param)) %mend nvalid;

41 Validating SAS Names The IMPRTXLS macro uses the NVALID autocall macro to determine if an Excel spreadsheet name is a valid data set name. 41 m204d05 %macro imprtxls(file); %local dsn; %let dsn=%scan(&file,-2,.\); %if not %nvalid(&dsn) %then %do; %put WARNING: Excel file name is not a valid SAS name.; %put WARNING- A default data set name of XLSFILE will be created.; %let dsn=xlsfile; %end; proc import datafile="&file" out=&dsn dbms=excel replace; mixed=yes; run; %mend imprtxls;

42 Validating SAS Names Partial SAS Log %imprtxls(s:\workshop\c4\order fact.xls) WARNING: Excel file name is not a valid SAS name. A default data set name of XLSFILE will be created. NOTE: Data source is connected in READ ONLY mode. NOTE: WORK.XLSFILE data set was successfully created. NOTE: PROCEDURE IMPORT used (Total process time): real time 0.20 seconds cpu time 0.12 seconds 767 %imprtxls(s:\workshop\c4\daily_sales.xls) NOTE: Data source is connected in READ ONLY mode. NOTE: WORK.DAILY_SALES data set was successfully created. NOTE: PROCEDURE IMPORT used (Total process time): real time 0.17 seconds cpu time 0.12 seconds m204d05

43 Simplifying the Use of SAS File I/O Functions The Orion Star programmers see an increased use of the SAS File I/O functions to extract data set attributes. 43 %let dsid=%sysfunc(open(orion.daily_sales)); %let nobs=%sysfunc(attrn(&dsid,nlobs)); %let dsidc=%sysfunc(close(&dsid)); options nodate nonumber; proc print data=orion.daily_sales; title "ORION.DAILY_SALES contains "; title2 "&nobs observations"; run;

44 Macro Version of the ATTRC Function To simplify programs extracting data set attributes, the Orion Star programmers created a macro version of the ATTRC and ATTRN functions. Both autocall macros will return an attribute’s value. 44 attrc %macro attrc(dsn,attr); %local dsid attrc dsidc; %let dsid=%sysfunc(open(&dsn)); %let attrc=%sysfunc(attrc(&dsid,&attr)); %let dsidc=%sysfunc(close(&dsid)); &attrc %mend attrc;

45 Macro Version of the ATTRN Function 45 attrn %macro attrn(dsn,attr); %local dsid attrn dsidc; %let dsid=%sysfunc(open(&dsn)); %let attrn=%sysfunc(attrn(&dsid,&attr)); %let dsidc=%sysfunc(close(&dsid)); &attrn %mend attrn;

46

Quiz 1.Open the program m204a02. 2.Replace the question marks with the ATTRN autocall macro to extract the logical number of observations in a data set. 47 m204a02 options nodate nonumber; proc print data=orion.daily_sales; title "ORION.DAILY_SALES contains "; title2 "?????????? observations"; run;

Quiz – Correct Answer 1.Open the program m204a02. 2.Replace the question marks with the ATTRN autocall macro to extract the logical number of observations in a data set. 48 m204a02 options nodate nonumber; proc print data=orion.daily_sales; title "ORION.DAILY_SALES contains "; title2 "%attrn(orion.daily_sales, nlobs) observations"; run; 1.Open the program m204a02. 2.Replace the question marks with the ATTRN autocall macro to extract the logical number of observations in a data set.

Quiz i – Output 49 ORION.DAILY_SALES contains 58 observations Obs Product_ID Product_Name Total_Retail_Price Pro Fit Gel Gt 2030 Women's Running Shoes $ Big Guy Men's Air Terra Sebec Shoes $ Bretagne Performance Tg Men's Golf Shoes L. $ Armadillo Road Dmx Women's Running Shoes $ Hardcore Men's Street Shoes Large $ Bretagne Stabilites 2000 Goretex Shoes $ Big Guy Men's Air Deschutz Viii Shoes $ Big Guy Men's Air Terra Reach Shoes $ Lulu Men's Street Shoes $ Bretagne Stabilities Tg Men's Golf Shoes $ Trooper Ii Dmx-2x Men's Walking Shoes $ South Peak Men's Running Shoes $ Shoelace White 150 Cm $ Hilly Women's Crosstrainer Shoes $ Bretagne Stabilities Tg Men's Golf Shoes $ Rubby Men's Golf Shoes w/Goretex Plain Toe $ Twain Men's Exit Low 2000 Street Shoes $ Power Women's Dmx Wide, Walking Shoes $ Kids Baby Edge Max Shoes $ Tony's Children's Deschutz (Bg) Shoes $41.60

50 Determining the Age of a SAS Data Set Many of Orion Star’s applications require determining the age of a data set. The programmers want to replace complex code with a single macro call. 50 age %macro age(dsn); %local dsid crdate dsidc days; %let dsid=%sysfunc(open(&dsn)); %let crdate=%sysfunc(attrn(&dsid,crdte)); %let dsidc=%sysfunc(close(&dsid)); %let days=%sysevalf("%today"d -%sysfunc(datepart(&crdate))); &days %mend age;

51 Using the AGE Macro This demonstration illustrates using the AGE autocall macro to determine whether a data set needs to be refreshed. 51 m204d06

52 User-Defined Macro Operators Operators in macro expressions are a subset of those in the DATA step. The macro facility does not recognize the IN operator in releases prior to SAS 9.2 the BETWEEN operator the colon (:) modifier. Macros can be written to simulate the functionality of these operators, producing a Boolean result. 52

53 The User-Defined FIND Operator Orion Star is still running SAS 9.1 on some servers and created the FIND macro as an alternative to the IN operator to simplify %IF logic. 53 m204d07 %macro grplist(type); %if %find(GOLD INTERNET,&type)=0 %then %do; %put ERROR: Value of TYPE: &type is not valid.; %put ERROR- Valid values are INTERNET or GOLD; %return; %end; %let type=%upcase(&type); proc print data=orion.customer_dim; var Customer_Group Customer_Name Customer_Gender Customer_Age; where upcase(Customer_Group) contains "&type"; title "&type Customers"; run; %mend grplist;

54 The User-Defined FIND Operator The FIND macro uses the INDEXW function to search a character expression for a string that is specified as a word. Although the INDEXW function returns the position of the first character in the word, the FIND macro returns a 1 if the value is found or a 0 if it is not. 54 find %macro find(source,string); %let source=%upcase(&source); %let string=%upcase(&string); %if %sysfunc(indexw(&source,&string))>0 %then 1; %else 0; %mend find;

55 The User-Defined FIND Operator The GRPLIST macro uses the FIND autocall macro to check the value of the parameter TYPE. 55 m204d07 %macro grplist(type); %if %find(GOLD INTERNET,&type)=0 %then %do; %put ERROR: Value of TYPE: &type is not valid.; %put ERROR- Valid values are INTERNET or GOLD; %return; %end; %let type=%upcase(&type); proc print data=orion.customer_dim; var Customer_Group Customer_Name Customer_Gender Customer_Age; where upcase(Customer_Group) contains "&type"; title "&type Customers"; run; %mend grplist;

56 The User-Defined FIND Operator Partial SAS Log %grplist(silver) MPRINT(GRPLIST): options nomlogic; ERROR: Value of TYPE: silver is not valid. Valid values are INTERNET or GOLD 152 %grplist(Internet) MPRINT(GRPLIST): proc print data=orion.customer_dim; MPRINT(GRPLIST): var Customer_Group Customer_Name Customer_Gender Customer_Age; MPRINT(GRPLIST): where upcase(Customer_Group) contains "INTERNET"; MPRINT(GRPLIST): title "INTERNET Customers"; MPRINT(GRPLIST): run; NOTE: There were 8 observations read from the data set ORION.CUSTOMER_DIM. WHERE UPCASE(Customer_Group) contains 'INTERNET'; NOTE: PROCEDURE PRINT used (Total process time): real time 0.01 seconds cpu time 0.03 seconds m204d07

57 Creating a Macro Version of the BETWEEN Operator To simplify %IF statement logic, the Orion Star programmers created a macro version of the BETWEEN operator to check a range of values. 57 %macro between(var,low,high); %sysevalf(&var >= &low and &var <= &high) %mend between; between

58 Creating a Macro Version of the BETWEEN Operator The BETWEEN autocall macro made parameter validation easier to maintain for the Orion Star programmers. 58 %macro monorder(month, year); %if not(%between(&month,1,12)) or not(%between(&year,2003,2007)) %then %do; %put ERROR: Month is not between 1 and 12 or; %put ERROR- Year is not between 2003 and 2007.; %put ERROR- The macro will stop executing.; %return; %end; data monthorders; set orion.order_fact; where month(Order_Date)=&month and year(Order_Date)=&year; DaysToShip=Delivery_Date-Order_Date; run; proc print data=monthorders; var Order_ID Order_Date Delivery_Date DaysToShip; title "Orders for &month/&year"; run; title; %mend monorder; m204d08

59 Creating a Macro Version of the BETWEEN Operator Partial SAS Log %monorder(1,2007) NOTE: There were 13 observations read from the data set ORION.ORDER_FACT. WHERE (MONTH(Order_Date)=1) and (YEAR(Order_Date)=2007); NOTE: The data set WORK.MONTHORDERS has 13 observations and 13 variables. NOTE: DATA statement used (Total process time): real time 0.00 seconds cpu time 0.00 seconds NOTE: There were 13 observations read from the data set WORK.MONTHORDERS. NOTE: PROCEDURE PRINT used (Total process time): real time 0.00 seconds cpu time 0.00 seconds 694 %monorder(13,2007) ERROR: Month is not between 1 and 12 or Year is not between 2003 and The macro will stop executing. m204d08

60 Creating a Macro Version of the =: Operator (Self-Study) The =: operator allows for comparison on a specified prefix of a character string. 60 %macro starts(string,search,case); %if %upcase(&case)=N or &case= %then %do; %let string=%upcase(&string); %let search=%upcase(&search); %end; %if %substr(&string,1,%length(&search))= &search %then 1; %else 0; %mend starts; starts

61 Creating a Macro Version of the =: Operator (Self-Study) Partial SAS Log 61 %macro saleslst(jobtitle); 402 %if %starts(&jobtitle,SALES,N) %then %do; 403 proc print data=orion.sales; 404 where Job_Title="&jobtitle"; 405 format Birth_Date Hire_Date mmddyy10.; 406 run; 407 %end; 408 %else 409 %put ERROR: Job Title must start with SALES.; 410 %mend saleslst; 411 %saleslst(Sales Rep. I) NOTE: There were 63 observations read from the data set ORION.SALES. WHERE Job_Title='Sales Rep. I'; NOTE: PROCEDURE PRINT used (Total process time): 412 %saleslst(Manager) ERROR: Job Title must start with SALES. m204d09

62 Exercise This exercise reinforces the concepts discussed previously. 62