SAS Macro Dynamics - From Simple Basics to Powerful Invocations Rick Andrews, Office of the Actuary, CMS, Baltimore, MD

Similar documents
SAS Macro Dynamics: from Simple Basics to Powerful Invocations Rick Andrews, Office of Research, Development, and Information, Baltimore, MD

Introduction. Getting Started with the Macro Facility CHAPTER 1

Submitting SAS Code On The Side

Macros from Beginning to Mend A Simple and Practical Approach to the SAS Macro Facility

SAS Macro Language: Reference

Going Under the Hood: How Does the Macro Processor Really Work?

Arthur L. Carpenter California Occidental Consultants, Oceanside, California

Journey to the center of the earth Deep understanding of SAS language processing mechanism Di Chen, SAS Beijing R&D, Beijing, China

How to Create Data-Driven Lists

Functions vs. Macros: A Comparison and Summary

SAS Data Libraries. Definition CHAPTER 26

title1 "Visits at &string1"; proc print data=hospitalvisits; where sitecode="&string1";

Copy That! Using SAS to Create Directories and Duplicate Files

KEYWORDS Metadata, macro language, CALL EXECUTE, %NRSTR, %TSLIT

CHAPTER 7 Using Other SAS Software Products

Tired of CALL EXECUTE? Try DOSUBL

Tales from the Help Desk 5: Yet More Solutions for Common SAS Mistakes Bruce Gilsen, Federal Reserve Board

WHAT ARE SASHELP VIEWS?

Foundations and Fundamentals. SAS System Options: The True Heroes of Macro Debugging Kevin Russell and Russ Tyndall, SAS Institute Inc.

Programming Gems that are worth learning SQL for! Pamela L. Reading, Rho, Inc., Chapel Hill, NC

QUEST Procedure Reference

Macro Basics. Introduction. Defining and Using Macro Variables. Defining and Using Macros. Macro Parameters. Part 1. Chapter 1. Chapter 2.

Using Recursion for More Convenient Macros

Tales from the Help Desk 6: Solutions to Common SAS Tasks

SAS Macro. SAS Training Courses. Amadeus Software Ltd

SAS Programming Techniques for Manipulating Metadata on the Database Level Chris Speck, PAREXEL International, Durham, NC

Files Arriving at an Inconvenient Time? Let SAS Process Your Files with FILEEXIST While You Sleep

ABSTRACT INTRODUCTION THE GENERAL FORM AND SIMPLE CODE

The Power of PROC SQL Techniques and SAS Dictionary Tables in Handling Data

You deserve ARRAYs; How to be more efficient using SAS!

David S. Septoff Fidia Pharmaceutical Corporation

ABSTRACT: INTRODUCTION: WEB CRAWLER OVERVIEW: METHOD 1: WEB CRAWLER IN SAS DATA STEP CODE. Paper CC-17

Matt Downs and Heidi Christ-Schmidt Statistics Collaborative, Inc., Washington, D.C.

SAS Macro Programming for Beginners

ABSTRACT MORE THAN SYNTAX ORGANIZE YOUR WORK THE SAS ENTERPRISE GUIDE PROJECT. Paper 50-30

ABSTRACT INTRODUCTION MACRO. Paper RF

Introduction to the SAS Macro Facility

Simplifying Your %DO Loop with CALL EXECUTE Arthur Li, City of Hope National Medical Center, Duarte, CA

PLA YING WITH MACROS: TAKE THE WORK OUT OF LEARNING TO DO MACROS. Arthur L. Carpenter

Macro Quoting: Which Function Should We Use? Pengfei Guo, MSD R&D (China) Co., Ltd., Shanghai, China

Developing Data-Driven SAS Programs Using Proc Contents

Building Sequential Programs for a Routine Task with Five SAS Techniques

A Tutorial on the SAS Macro Language

Essential ODS Techniques for Creating Reports in PDF Patrick Thornton, SRI International, Menlo Park, CA

Get Started Writing SAS Macros Luisa Hartman, Jane Liao, Merck Sharp & Dohme Corp.

The Ins and Outs of %IF

Useful Tips When Deploying SAS Code in a Production Environment

An Introduction to SAS Macros

%MISSING: A SAS Macro to Report Missing Value Percentages for a Multi-Year Multi-File Information System

The Dataset Diet How to transform short and fat into long and thin

Sandra Hendren Health Data Institute

AN INTRODUCTION TO MACRO VARIABLES AND MACRO PROGRAMS Mike Zdeb, School of Public Health

How to Incorporate Old SAS Data into a New DATA Step, or What is S-M-U?

Using SAS to Control and Automate a Multi SAS Program Process Patrick Halpin, dunnhumby USA, Cincinnati, OH

Storing and Reusing Macros

More About SAS Macros

GET A GRIP ON MACROS IN JUST 50 MINUTES! Arthur Li, City of Hope Comprehensive Cancer Center, Duarte, CA

Greenspace: A Macro to Improve a SAS Data Set Footprint

STEP 1 - /*******************************/ /* Manipulate the data files */ /*******************************/ <<SAS DATA statements>>

Macro Internals for the User Developer s Overview. Susan O Connor, SAS Institute Inc., Cary, NC

Summarizing Impossibly Large SAS Data Sets For the Data Warehouse Server Using Horizontal Summarization

Make it a Date! Setting up a Master Date View in SAS

A Quick and Gentle Introduction to PROC SQL

Posters. Workarounds for SASWare Ballot Items Jack Hamilton, First Health, West Sacramento, California USA. Paper

How to Implement the One-Time Methodology Mark Tabladillo, Ph.D., Atlanta, GA

A Generic Solution to Running the SAS System on the Web Without SAS/Intrnet David L. Ward, InterNext, Inc., Somerset, NJ

SAS Institute Exam A SAS Advanced Programming Version: 6.0 [ Total Questions: 184 ]

Macro Facility. About the Macro Facility. Automatic Macro Variables CHAPTER 14

Text Generational Data Sets (Text GDS)

ABSTRACT INTRODUCTION TRICK 1: CHOOSE THE BEST METHOD TO CREATE MACRO VARIABLES

Understanding the Concepts and Features of Macro Programming 1

SELF-MODIFYING SAS PROGRAMS: A DATA STEP INTERFACE

Using PROC REPORT to Cross-Tabulate Multiple Response Items Patrick Thornton, SRI International, Menlo Park, CA

An Introduction to Macros Deb Cassidy

SAS PROGRAM EFFICIENCY FOR BEGINNERS. Bruce Gilsen, Federal Reserve Board

SAS PROGRAM EFFICIENCY FOR BEGINNERS. Bruce Gilsen, Federal Reserve Board

Bruce Gilsen, Federal Reserve Board

Macro Architecture in Pictures Mark Tabladillo PhD, marktab Consulting, Atlanta, GA Associate Faculty, University of Phoenix

<:ards,. The SAS" Macro: An Aid to the User 3' pfbl:me~~&j1tbc(lpt; 2435 procopt; RESOLVED RESOLVED

Different Methods for Accessing Non-SAS Data to Build and Incrementally Update That Data Warehouse

STATION

Macro to compute best transform variable for the model

Macros to Manage your Macros? Garrett Weaver, University of Southern California, Los Angeles, CA

PharmaSUG Paper SP04

Using GSUBMIT command to customize the interface in SAS Xin Wang, Fountain Medical Technology Co., ltd, Nanjing, China

PharmaSUG 2017 Paper BB02

Using MACRO and SAS/GRAPH to Efficiently Assess Distributions. Paul Walker, Capital One

Because We Can: Using SAS System Tools to Help Our Less Fortunate Brethren John Cohen, Advanced Data Concepts, LLC, Newark, DE

A Generalized Macro-Based Data Reporting System to Produce Both HTML and Text Files

PROC MEANS for Disaggregating Statistics in SAS : One Input Data Set and One Output Data Set with Everything You Need

Using PROC FCMP to the Fullest: Getting Started and Doing More

APPENDIX 4 Migrating from QMF to SAS/ ASSIST Software. Each of these steps can be executed independently.

A Format to Make the _TYPE_ Field of PROC MEANS Easier to Interpret Matt Pettis, Thomson West, Eagan, MN

How to Implement the One-Time Methodology Mark Tabladillo, Ph.D., MarkTab Consulting, Atlanta, GA Associate Faculty, University of Phoenix

DATA Step Debugger APPENDIX 3

PharmaSUG 2013 CC26 Automating the Labeling of X- Axis Sanjiv Ramalingam, Vertex Pharmaceuticals, Inc., Cambridge, MA

SAS Macro Programming Tips and Techniques

Using Different Methods for Accessing Non-SAS Data to Build and Incrementally Update That Data Warehouse

Sorting big datasets. Do we really need it? Daniil Shliakhov, Experis Clinical, Kharkiv, Ukraine

Using PROC SQL to Calculate FIRSTOBS David C. Tabano, Kaiser Permanente, Denver, CO

Transcription:

Paper BB-7 SAS Macro Dynamics - From Simple Basics to Powerful Invocations Rick Andrews, Office of the Actuary, CMS, Baltimore, MD ABSTRACT The SAS Macro Facility offers a mechanism for expanding and customizing the functionality of the SAS System. It allows for the abbreviation of a large amount of program code conveniently and makes textual substitutions easy. The facility contains a programming language enables the execution of small sections of a program or entire steps conditionally. This paper assumes a basic knowledge of the DATA step and the use of programming logic. It will provide simple to dynamics views of the powerful capabilities of SAS macros. INTRODUCTION CONTENTS SAS macros are evaluated before compile time. When a SAS program is submitted the system routes code to the macro processor and reviews the text to see if any SAS macros or macro variables have been included. The processor cycles through the macro calls, replaces any macro references with actual values, and releases the updated program to the compiler for further processing. The resulting effective code will be revealed throughout the paper. In general, the SAS macro language is portable across all operating systems with few exceptions. Typically, SAS statements that begin with a percent sign (%) are part of the macro language and macro variables can be identified by a proceeding ampersand (&). MACRO VARIABLES Macro Variables - %LET - PROC SQL - CALL SYMPUT Simple Macros - %MACRO - %IF-%THEN-%ELSE Dynamic Macros - %INCLUDE - CALL EXECUTE - %DO-%TO-%END Probably the simplest use of the SAS Macro Facility is the creation of macro variables. Macro variables should be used if the same value needs to be changed in more than one location each time a program is submitted. Macro variable definitions should be located at the top of a program. There are several ways to create macro variables, the easiest of which is the use of %LET. %LET WHERE CPT_CODE = '208'; SET SAS.DATASET2; WHERE CPT_CODE = '208'; Figure : Without Macro Variable %LET CPTCODE = '208'; WHERE CPT_CODE = &CPTCODE; SET SAS.DATASET2; WHERE CPT_CODE = &CPTCODE; Figure 2: With Macro Variable Note the use of single (') quotes surrounding the value of the macro variable CPTCODE in the example above. When resolved, the value of '208' will be passed to the compiler including the quotes. If the single quotes are omitted during the creation of the macro variable and instead are included within the WHERE clause, such as in the example Figure below left, the SAS system will pass the literal value of '&CPTCODE' NOT '208'. To resolve the macro variable in this manor it should be surrounded with double (") quotes as shown in Figure 4 below right. %LET CPTCODE = 208; WHERE CPT_CODE = '&CPTCODE'; Figure : Single Quotes %LET CPTCODE = 208; WHERE CPT_CODE = "&CPTCODE"; Figure 4: Double Quotes

PROC SQL Another way to create a macro variable is to use the SQL procedure. This is a good way to use values from within a data set that are needed for another process. In the data set, MY.DATA, a given value for the MEMBERS variable can be placed into a macro variable depending on the requirements of a process. In this example, the PROC SQL will grab the FIRST record in the data set. The macro variable MACVAR will resolve to 000. In this example, the PROC SQL will grab the record meeting the WHERE criteria. The variable MACVAR2 will resolve to 2000. PROC SQL NOPRINT; SELECT MEMBERS INTO : MACVAR FROM MY.DATA; QUIT; %PUT &MACVAR; *Result = 000; Figure 5: MACVAR CALL SYMPUT. MY.DATA YEAR MEMBERS 999 000 2000 2000 200 000 The %PUT will output the results to the LOG. PROC SQL NOPRINT; SELECT MEMBERS INTO : MACVAR2 FROM MY.DATA WHERE YEAR = 2000; QUIT; %PUT &MACVAR2; *Result = 2000; Figure 6: MACVAR2 The SYMPUT routine can be used to interact with the macro facility during the execution of a DATA step. The routine allows the creation of macro variables based on values within a SAS data set similar to the PROC SQL. A major difference is one process will resolve to the value of the LAST record in lieu of the FIRST! In this example, the CALL SYMPUT will grab the LAST record in the table. The macro variable MACVAR will resolve to 000. In this example, the CALL SYMPUT will grab the record meeting the WHERE criteria. The variable MACVAR4 will resolve to 2000. SET MY.DATA; CALL SYMPUT('MACVAR', MEMBERS); %PUT &MACVAR; *Result = 000; Figure 7: MACVAR DYNAMIC IN (LIST) MY.DATA YEAR MEMBERS 999 000 2000 2000 200 000 DATA _NULL_ tells SAS not to create a data set. SET MY.DATA; WHERE YEAR = 2000; CALL SYMPUT('MACVAR4', MEMBERS); %PUT &MACVAR4; *Result = 2000; Figure 8: MACVAR4 PROC SQL can also be used to string values together. This is particularly useful when an IN list is needed for use within a WHERE clause. Consider the data set, MY.CPTDATA, where a list of CPT_CODEs has been stored. This list can be placed into a macro variable and used as such: WHERE CPT_CODE IN ( &MYLIST ). MY.CPTDATA CPT_CODE 208 2082 208 2084 2085 PROC SQL NOPRINT; SELECT "'" CPT_CODE "'" INTO : MYLIST SEPARATED BY ',' FROM MY.CPTDATA; QUIT; %PUT &MYLIST; *RESULT = '208','2082','208','2084','2085'; Figure 8a: MYLIST 2

SIMPLE MACROS Placement of SAS code within macros has various advantages. ) Program code reduction 2) Eliminate repetitive changes ) Provide conditional execution 4) Reduce typing errors. Below are examples of simple macro executions. %MACRO This simple example of a SAS macro actually does nothing more than execute the DATA step TEMP0. %MACRO EXAMPLE; DATA TEMP0; %MEND EXAMPLE; %EXAMPLE Figure 9: Program Code EXAMPLE This example demonstrates how to pass values into the macro for use within the DATA step. %MACRO EXAMPLE2(MACVAR,CPTCODE); DATA TEMP&MACVAR; WHERE CPT_CODE = "&CPTCODE"; %MEND EXAMPLE2; %EXAMPLE2 (, 208 ) %EXAMPLE2 ( 2, 2082 ) Figure 0: Program Code EXAMPLE2 In order to signify the beginning of a SAS macro the keyword %MACRO tells the processor the word that follows, such as EXAMPLE shown in Figure 9, will be the reference used to CALL the macro later in the program. The processor keeps reading the program until it reaches the keyword, %MEND, at which point it knows the macro creation has ended. The syntax at right demonstrates the effective code created after the program has passed through the macro processor. This is the code the SAS compiler will see. Note the difference between the data set names (i.e. TEMP and TEMP2) and the values passed into the WHERE clause. %IF - %THEN - %ELSE The macro in EXAMPLE may seem somewhat superfluous for there is no need for the macro given that no values are being passed and nothing has changed. One useful purpose for creating a macro with no parameters is to conditionally WHERE CPT_CODE="208"; WHERE CPT_CODE="2082"; Figure : Effective Code EXAMPLE2 execute program code. The next example shows how to check whether a file already exists before trying to create it. Checking for the existence of a file can be done for SAS data sets, libraries, directories, and external files as shown. OPEN CODE A statement submitted using the macro language instructs the SAS macro processor to evaluate a given operation before compile time. Some statements are only allowed inside a macro definition (between the %MACRO and %MEND statements.) There are instances when parts of the macro language can be submitted in OPEN CODE, which essentially means outside of the macro definition. Examples of this functionality include %LET and %PUT. The %IF and %DO in the example shown here cannot be executed in OPEN CODE. %MACRO EXAMPLE; CALL SYMPUT( 'EXISTS', OPEN('TEMP','I') ); %IF NOT &EXISTS %THEN %DO; %ELSE %DO; %PUT ERROR WILL ROGERS!; %MEND EXAMPLE; %EXAMPLE Figure 2: Program Code EXAMPLE OPEN - Opens SAS data set. See also: FOPEN Opens external file. DOPEN Opens a directory. FEXIST Determine if external file exists.

DYNAMIC MACROS Creating a dynamic macro call based on values within a data set is relatively straight forward. Figure below demonstrates how to use a list of codes from a data set and create a macro that will cycle for each record. The macro EXAMPLE4 will accept two positional parameters, MACVAR and CPTCODE, same as in EXAMPLE2 on page 2. DATA _NULL_ MY.CPTDATA CPT_CODE 208 2082 208 2084 2085 The function of DATA _NULL_ in this step is to output a SAS macro call to a temporary program using the FILE statement. The _N_ is the temporary variable used to count the iterations of the DATA step. Here it can be used to count observations, though not its primary function. This automatic SAS variable and the CPT_CODE variable are used within the PUT statement to create the appropriate number of SAS macro calls based on the information within the data set, MY.CPTDATA. * CREATE A MACRO TO PERFORM A GIVEN TASK *; %MACRO EXAMPLE4 ( MACVAR, CPTCODE ); DATA TEMP&MACVAR; WHERE CPT_CODE = "&CPTCODE"; %MEND EXAMPLE4; * CREATE OUTPUT FILE CONTAINING MACRO CALL *; FILENAME TMP_FIL TEMP; SET MY.CPTDATA; FILE TMP_FIL; PUT '%EXAMPLE4(' _N_ ',' CPT_CODE ')' ; * INCLUDE FILE CONTAINING MACRO CALL *; %INCLUDE TMP_FIL; 2 %INCLUDE 2 Figure : Program Code EXAMPLE4 When the %INCLUDE statement is executed the syntax of the SAS program within the temporary file is read by the macro processor and the SAS macro calls are then evaluated. The subsequent effective code is passed to the compiler. At execution time, the system will process the 5 data steps shown below. If the number of observations within MY.CPTDATA changes, the macro will dynamically execute as many macro calls as becomes necessary. %EXAMPLE4 (, 208 ) %EXAMPLE4 ( 2, 2082 ) %EXAMPLE4 (, 208 ) %EXAMPLE4 ( 4, 2084 ) %EXAMPLE4 ( 5, 2085 ) Figure 4: Macro Calls in Temporary File WHERE..."208"; WHERE..."2082"; DATA TEMP; WHERE..."208"; DATA TEMP4; WHERE..."2084"; DATA TEMP5; WHERE..."2085"; Figure 5: Effective Code Example4 CALL EXECUTE The EXECUTE subroutine sends character arguments to the input stream, executes them immediately, and returns to the calling module, in this case, the DATA step. This is truly a gem of a routine as it eliminates the need for the temporary file. Note the similarity to the PUT statement above, the major difference being the concatenation symbols ( ) and parenthesis that surround the statement. * SUBMIT EXAMPLE5 FOR EACH CPT CODE *; SET MY.CPTDATA; CALL EXECUTE ( '%EXAMPLE5(' _N_ ',' CPT_CODE ')' ); Figure 6: Program Code CALL SYMPUT 4

%DO-%TO-%END The program that follows will produce the same effective code as the previous two examples. The result being five DATA steps passed to the SAS compiler for processing. Here the process will dynamically LOOP through the data using an array of macro variables. DATA _NULL_ MY.CPTDATA CPT_CODE 208 2082 208 2084 2085 The _N_ variable is used during the creation of the MACVAR variables and to create the TOTOBS macro variable. It should be noted that _N_ should be used with caution when counting observations. If the DATA step contains a DO loop, _N_ may get incremented for each iteration of the loop. It can only be used as a count of records in selective cases. During the first iteration of the DATA step, the CALL SYMPUT creates a macro variable called MACVAR that contains the value of the CPT code for the FIRST record in the data set. Each subsequent iteration creates an additional macro variable corresponding to the record currently in memory. The effective code of this step is shown in Figure 8. %MACRO LOOP; %DO I= %TO &TOTOBS; %EXAMPLE6; %MEND LOOP; %LOOP; * CREATE A MACRO TO PERFORM A GIVEN TASK *; %MACRO EXAMPLE6; DATA TEMP&I; WHERE CPT_CODE = "&&MACVAR&I"; %MEND EXAMPLE6; * NOTE THE DOUBLE AMPERSAND! *; * DEFINE MACRO VARIABLES *; SET MY.CPTDATA; CALL SYMPUT( 'MACVAR' LEFT(TRIM(_N_)), CPT_CODE ); CALL SYMPUT( 'TOTOBS', _N_ ); * SUBMIT EXAMPLE5 FOR EACH CPT CODE *; %MACRO LOOP; %DO I= %TO &TOTOBS; %EXAMPLE6; %MEND LOOP; %LOOP; %LET MACVAR = 208; %LET MACVAR2 = 2082; %LET MACVAR = 208; Figure 7: Program Code EXAMPLE6 2 %LET MACVAR4 = 2084; %LET MACVAR5 = 2085; %LET TOTOBS = 5; MACRO LOOP 2 Figure 8: Effective Code EXAMPLE6 The SAS macro called LOOP has no positional parameters. Nothing is being passed into it. The %DO-%TO-%END is SAS macro code and is only executed from within a SAS macro. In other words, they cannot be executed in OPEN CODE. Here the process will execute the %EXAMPLE6 macro for the total number of observations within the TOTOBS macro variable, 5 in this case as shown in the effective code. Figure 9: Macro LOOP DOUBLE AMPERSAND && The final step of the program in Figure 7 evaluates the double ampersand &&. During the execution of the %DO LOOP, a new macro variable I was created. This macro variable contains the current iteration of the LOOP. The first time through, it evaluates to, then 2, and so on until it reaches 5. The evaluation of the &&MACVAR&I variable is more complicated. The result created by the double ampersand during the first iteration will be, &MACVAR, which then resolves to 208. Each subsequent iteration of the %DO LOOP yields an increasing number, &MACVAR2, &MACVAR, based on the value of &I. %MACRO EXAMPLE6; DATA TEMP&I; GEE = "&&MACVAR&I"; WHIZ = &I; %MEND EXAMPLE6; Figure 20: Macro EXAMPLE6 5

CONCLUSION The SAS Macro Facility is a very powerful scripting language and can be employed to create very dynamic processes with ever increasing functionality. It would behoove every SAS programmer, statistician, and analyst to learn more about this robust facility. The applications shown here range from the most basic to the somewhat intricate, though only begin to scratch the surface of the capabilities. REFERENCES Carpenter, A. (2005), Storing and Using a List of Values in a Macro Variable, Proceedings of the Thirtieth Annual SAS Users Group International Conference, 0, 028-0. Varney, B. (999), Creating Data Driven Programs with the Macro Language Proceedings of the Twenty-fourth Annual SAS Users Group International Conference, 24, 254-24. Denis M. (2005), CALL EXECUTE: A Powerful Data Management Tool, Proceedings of the Thirtieth Annual SAS Users Group International Conference, 0, 027-0. SAS Institute Inc. (990), SAS Guide to Macro Processing, Version 6, Second Edition. Cary, NC: SAS Institute Inc. SAS Institute Inc. 999, SAS OnlineDoc Version Eight. SAS Macro Language Reference. http://v8doc.sas.com/sashtml/. ACKNOWLEDGMENTS The author wishes to thank the CMS SAS User Group for their support. CONTACT INFORMATION Your comments and questions are valued and encouraged. Rick Andrews Office of the Actuary Centers for Medicare and Medicaid Services 7500 Security Boulevard Baltimore, MD 2244 Phone: (40) 786-695 E-mail: Richard.Andrews2@cms.hhs.gov SAS and all other SAS Institute Inc. product or service names are registered trademarks or trademarks of SAS Institute Inc. in the USA and other countries. indicates USA registration. 6