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

Similar documents
Get into the Groove with %SYSFUNC: Generalizing SAS Macros with Conditionally Executed Code

Planting Your Rows: Using SAS Formats to Make the Generation of Zero- Filled Rows in Tables Less Thorny

Let SAS Write and Execute Your Data-Driven SAS Code

A Practical and Efficient Approach in Generating AE (Adverse Events) Tables within a Clinical Study Environment

There s No Such Thing as Normal Clinical Trials Data, or Is There? Daphne Ewing, Octagon Research Solutions, Inc., Wayne, PA

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

Paper An Automated Reporting Macro to Create Cell Index An Enhanced Revisit. Shi-Tao Yeh, GlaxoSmithKline, King of Prussia, PA

Using SAS Macro to Include Statistics Output in Clinical Trial Summary Table

PharmaSUG Paper SP04

An Efficient Method to Create Titles for Multiple Clinical Reports Using Proc Format within A Do Loop Youying Yu, PharmaNet/i3, West Chester, Ohio

SAS Macros for Grouping Count and Its Application to Enhance Your Reports

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

Introduction. Getting Started with the Macro Facility CHAPTER 1

186 Statistics, Data Analysis and Modeling. Proceedings of MWSUG '95

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

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

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

Developing Data-Driven SAS Programs Using Proc Contents

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

PROC REPORT AN INTRODUCTION

Clinical Data Visualization using TIBCO Spotfire and SAS

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

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

Validation Summary using SYSINFO

Using SAS Macros to Extract P-values from PROC FREQ

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

BY S NOTSORTED OPTION Karuna Samudral, Octagon Research Solutions, Inc., Wayne, PA Gregory M. Giddings, Centocor R&D Inc.

A Side of Hash for You To Dig Into

So Much Data, So Little Time: Splitting Datasets For More Efficient Run Times and Meeting FDA Submission Guidelines

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

Compute; Your Future with Proc Report

BreakOnWord: A Macro for Partitioning Long Text Strings at Natural Breaks Richard Addy, Rho, Chapel Hill, NC Charity Quick, Rho, Chapel Hill, NC

Please Don't Lag Behind LAG!

Using PROC PLAN for Randomization Assignments

Paper PO06. Building Dynamic Informats and Formats

Advanced Visualization using TIBCO Spotfire and SAS

PharmaSUG Paper TT11

A General SAS Macro to Implement Optimal N:1 Propensity Score Matching Within a Maximum Radius

An Efficient Tool for Clinical Data Check

%MAKE_IT_COUNT: An Example Macro for Dynamic Table Programming Britney Gilbert, Juniper Tree Consulting, Porter, Oklahoma

Better Metadata Through SAS II: %SYSFUNC, PROC DATASETS, and Dictionary Tables

9 Ways to Join Two Datasets David Franklin, Independent Consultant, New Hampshire, USA

SAS Macro Language: Reference

Reading a Column into a Row to Count N-levels, Calculate Cardinality Ratio and Create Frequency and Summary Output In One Step

Ditch the Data Memo: Using Macro Variables and Outer Union Corresponding in PROC SQL to Create Data Set Summary Tables Andrea Shane MDRC, Oakland, CA

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

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

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

Statistics and Data Analysis. Common Pitfalls in SAS Statistical Analysis Macros in a Mass Production Environment

JMP Clinical. Release Notes. Version 5.0

Arthur L. Carpenter California Occidental Consultants, Oceanside, California

Using V9 ODS LAYOUT to Simplify Generation of Individual Case Summaries Ling Y. Chen, Rho, Inc., Newton, MA

The Proc Transpose Cookbook

Customized Flowcharts Using SAS Annotation Abhinav Srivastva, PaxVax Inc., Redwood City, CA

Getting Up to Speed with PROC REPORT Kimberly LeBouton, K.J.L. Computing, Rossmoor, CA

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

A Few Quick and Efficient Ways to Compare Data

Indenting with Style

WHAT ARE SASHELP VIEWS?

Utilizing SAS for Cross- Report Verification in a Clinical Trials Setting

Getting it Done with PROC TABULATE

CHAPTER 7 Examples of Combining Compute Services and Data Transfer Services

PhUse Practical Uses of the DOW Loop in Pharmaceutical Programming Richard Read Allen, Peak Statistical Services, Evergreen, CO, USA

A Breeze through SAS options to Enter a Zero-filled row Kajal Tahiliani, ICON Clinical Research, Warrington, PA

Generating Customized Analytical Reports from SAS Procedure Output Brinda Bhaskar and Kennan Murray, RTI International

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

Using Data Set Options in PROC SQL Kenneth W. Borowiak Howard M. Proskin & Associates, Inc., Rochester, NY

Facilitate Statistical Analysis with Automatic Collapsing of Small Size Strata

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

HOW TO EFFECTIVELY DEAL WITH HARDCODING AND CDISC CONTROLLED TERMINOLOGY IN CLINICAL STUDIES

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

Out of Control! A SAS Macro to Recalculate QC Statistics

A Simple Framework for Sequentially Processing Hierarchical Data Sets for Large Surveys

Cleaning Duplicate Observations on a Chessboard of Missing Values Mayrita Vitvitska, ClinOps, LLC, San Francisco, CA

In this paper, we will build the macro step-by-step, highlighting each function. A basic familiarity with SAS Macro language is assumed.

If You Need These OBS and These VARS, Then Drop IF, and Keep WHERE Jay Iyengar, Data Systems Consultants LLC

A Tutorial on the SAS Macro Language

Want to Do a Better Job? - Select Appropriate Statistical Analysis in Healthcare Research

Merging Data Eight Different Ways

Two useful macros to nudge SAS to serve you

%ANYTL: A Versatile Table/Listing Macro

Program Validation: Logging the Log

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

Macros for Two-Sample Hypothesis Tests Jinson J. Erinjeri, D.K. Shifflet and Associates Ltd., McLean, VA

Chapter 6: Modifying and Combining Data Sets

Statistics, Data Analysis & Econometrics

PharmaSUG China 2018 Paper AD-62

T.I.P.S. (Techniques and Information for Programming in SAS )

Data Quality Review for Missing Values and Outliers

Get SAS sy with PROC SQL Amie Bissonett, Pharmanet/i3, Minneapolis, MN

Practical Uses of the DOW Loop Richard Read Allen, Peak Statistical Services, Evergreen, CO

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

Tweaking your tables: Suppressing superfluous subtotals in PROC TABULATE

PROC REPORT Basics: Getting Started with the Primary Statements

Give me EVERYTHING! A macro to combine the CONTENTS procedure output and formats. Lynn Mullins, PPD, Cincinnati, Ohio

Efficient Processing of Long Lists of Variable Names

PharmaSUG China. Systematically Reordering Axis Major Tick Values in SAS Graph Brian Shen, PPDI, ShangHai

Guide Users along Information Pathways and Surf through the Data

Transcription:

Generalized Report Programming Techniques Using Data-Driven SAS Code Kathy Hardis Fraeman, A.K. Analytic Programming, L.L.C., Olney, MD Karen G. Malley, Malley Research Programming, Inc., Rockville, MD ABSTRACT The SAS data step functions included in version 6.12, based on Screen Control Language (SCL) functions, provide tools for writing generalized macros. These generalized macros can determine characteristics of input variables such as variable type, length, and format and then customize the macro-generated code based on these variables characteristics. Using this technique combined with the SAS macro facility, we have programmed several generalized SAS macros that produce standard reports used in clinical drug studies. Examples of standard clinical study reports that have been generalized include Adverse Event Severity and Relationship to Treatment and Statistical Comparison of Treatment Groups at Baseline. The names of report variables found in a specific clinical study s data are supplied as input parameters to these macros, and the resulting SAS programs generated by these macros are customized to the specific characteristics of each study s data. The customized programs include the study-specific variable names and characteristics, and customized code relating to each variable s possible and/or actual data values. macros don t require any study-specific modifications. The purpose of this paper is to share some of the techniques used to write general report program macros using data-driven SAS code. The generalized reporting systems have two main components the study-specific front end and the general report macro. The study-specific front end performs all of the study-specific data processing. After that processing has been completed, the program then calls the general report macro. STUDY-SPECIFIC FRONT END The study-specific front end performs three separate steps before it calls the general report macro. It manipulates the data to meet the needs of the study and the report macro, assigns the names of the input SAS data set and data set variables to global macro variables, and calls a setup macro. The steps included in a general version of the studyspecific front end code are shown below. INTRODUCTION SAS programmers often modify report programs originally written for one study to be used with another study. The programs need to be modified to accommodate the differences in SAS data from the different studies. The two general types of such modification involve the studyspecific, front end processing required to prepare data for report generation and the differences in variable names, formats, and types for analogous variables between the different studies. Front end data processing is usually study-specific. A study s data may need to be restructured, normalized, merged, concatenated, subsetted, interleaved or processed through any of a variety of data step functions. Further, once the data are structured correctly for the report, specific variables in the data may need to be derived, categorized, reformatted, concatenated, or split. These variable manipulations are also usually studyspecific. The second general type of difference in data sets for different studies are the differences in the characteristics of the analogous variables. For example, a variable representing treatment group in a clinical study can be character or numeric, formatted or unformatted, and, inevitably, will have a different variable name. Depending on study design, this variable can also have two or more different values. The new data step functions in SAS 6.12 that determine the physical attributes of a variable, combined with the SAS Macro language and good structured programming techniques, have enabled us to write generalized report macros for commonly generated reports. These general STUDY-SPECIFIC FRONT END PROGRAM STEPS STEP 1 - /*******************************/ /* Manipulate the data files */ /*******************************/ <<SAS DATA statements>> STEP 2 - /* Assign the input data and variable */ /* names to global macro variables */ %global<<report macro data set name(s)>> <<report macro variable name(s)>>; %let <<report macro data set name>> = <<data set name>>; %let <<report macro variable name>> = <<variable name>>; STEP 3 - /* Get the variable information to */ /* set up the report macro */ %setup(<<report macro data set name>> = &<<report macro data set name, <<report macro variable name>> = &<<report macro variable name>>) STEP 4 - /***********************************/ /* Call the general report macro */ /***********************************/ %report

STEP 1 - DATA MANIPULATIONS No matter how much we may wish otherwise, data from individual studies usually have their own special data processing needs. Study data must be manipulated in unique ways before they can be used to generate a report. Unfortunately, this step usually cannot be generalized. However, good structured programming practice dictates that all of these study-specific data manipulations be contained in only one section of code. This section of SAS code can be as short or as long as warranted by the data requirements. The primary goal is to put the data into the format required by the general report macro, usually requiring one or more DATA statements. A very simple example of data manipulations could be a simple DATA statement with a MERGE. STEP 3 - SETUP VARIABLE INFORMATION A general report macro needs to know not only the names of the specific variables to use in the report, but also those variables characteristics. Additional macro variables are generated using the new SAS data step functions that describe the characteristics of these variables. These additional macro variables can then be used in the general report macro to generate report code conditionally based on the variables characteristics. A call to the setup macro for a general report would look like this. STEP 3 CODE EXAMPLE %setup(_data=&_data, _grpvar=&_grpvar, _statvar=&_statvar) STEP 1 - CODE EXAMPLE data dsn (keep = txgroup age merge in.main in.demog; by patid; STEP 2 - MACRO ASSIGNMENTS Once the data have the correct structure and format required by both the needs of the study and the general report macro, the study-specific front end assigns the names of the input SAS data set (or sets) and data set variables to global macro variables. If the general report macro needs to know the name of one input data set and two data set variables, the macro definition code would read as below. The macro variable names of variables in our general report macros always begin with the prefix _ and end with the suffix var. An example of the code for a SETUP macro with two input variables, _grpvar and _statvar, is given below. %MACRO SETUP CODE - EXAMPLE /******************************************/ /* Macro name : SETUP */ /* Purpose: Gets global macro variables */ /* that describe the study variables */ /* Called by: Study-specific front end */ /******************************************/ %macro setup(_data=, /* input data set */ _grpvar=, /* group variable */ _statvar= /* statistic var */ %if %sysfunc(exist(&_data)) %then %do; %let dsid = %sysfunc(open(&_data,i) %varinfo(var=_grp, dsid=&dsid) %varinfo(var=_stat, dsid=&dsid) %let rc = %sysfunc(close(&dsid) %else %put ERROR DSN does not exist; %mend setup; STEP 2 CODE EXAMPLE %global _data _grpvar _statvar; %let _data = dsn; %let _grpvar = txgroup; %let _statvar = age; where _data is the macro variable name of the data set in the general report macro; dsn is the name of the input data set; _grpvar and _statvar are the macro variable names of variables in the general report macro; and txgroup and age are the names of the variables in the input data set, dsn. The above code uses the new variable functions EXIST, OPEN, and CLOSE. EXIST determines whether the data set actually exists. Although its use is not required before opening a data set, it can generate an error message if the data set does not exist. OPEN opens the data set so other functions can access information about variables in the data set. It also generates a data set identification number to be used by other variable functions. CLOSE closes the data set so it can accessed for other uses. An opened data set will be locked until it is specifically closed.

The macro %VARINFO determines the variables characteristics and stores them in additional global macro variables. %MACRO VARINFO DETERMINE VARIABLE CHARACTERISTICS /* Macro name : VARINFO */ /* Purpose: Gets global variable */ /* description variables */ /* Called by: macro SETUP */ /* Input: VAR-Prefix for variable */ /* named VARvar */ /* DSID-Data set id of data set*/ /* containing VARvar */ /* Output: VARTYP-Type of variable */ /* (C or N) */ /* VARLEN-Variable length */ /* VARFMT-Variable format */ %macro varinfo(var=, /*prefix */ dsid= /*data set id*/ %global &var.typ &var.len &var.fmt; %let varnum = %sysfunc(varnum(&dsid,&&&var.var) %let &var.typ = &sysfunc(vartype(&dsid,&varnum) %let &var.len = %sysfunc(varlen(&dsid,&varnum) %let &var.fmt = %sysfunc(varfmt(&dsid,&varnum) %mend varinfo; The above code uses the new variable functions VARNUM, VARTYPE, VARLEN, and VARFMT. VARNUM retrieves the variable number for a specific variable name within an opened data set and is required to obtain any other information about the variable. VARTYPE, VARLEN, and VARFMT return the type, length and format associated with a variable. Other data step functions that determine a variable s physical attributes are summarized in the reference New Data Step Functions in SAS 6.12 Data Set and Variable Functions. These global macro variables VARtyp, VARlen, and VARfmt can be used in the general report macro to generate code conditionally based on the variable VARvar s characteristics. STEP 4 CALL TO GENERAL REPORT MACRO The final step of the study-specific front end calls the general REPORT macro. The remainder of the paper summarizes data-driven programming techniques used in writing general report macros. GENERAL REPORT MACRO General report macros contain nothing specific about any data in any data set for any study. All code relating to variables names, characteristics, or actual data values is data-driven and conditionally generated. Three general programming techniques are used to write generalized, data-driven SAS code. These techniques include conditional generation of code based on the global macro variables describing the data variables characteristics; the CALL EXECUTE macro function to generate SAS code based on actual data values found in a data set; and conditional generation of code based on actual data values found in a data set. The following examples show programming techniques used in a hypothetical general report macro, %MACRO REPORT. TECHNIQUE 1 - CONDITIONALLY GENERATED SAS CODE BASED ON VARIABLE CHARACTERISTICS The following code shows an example of conditional code generation, based on variable type, found in a general macro. CONDITIONAL CODE - EXAMPLE 1 /* Combine summary statistics for */ /* group and total */ data sumstat; set out outall(in=all /* Assign total group value based */ /* on type */ %if &_grptyp = C %then %do; if all then &_grpvar = 99 ; %else %if &_grptyp = N %then %do; if all then &_grpvar = 99; &_Grptyp is the global macro variable generated in the study-specific front end that gives the type (character or numeric) of the group variable. If the type of the group variable is character, then its length must be at least 2 for the above code to work. Additional code can be added to conditionally create a new temporary group variable with a length of 2 if the length of the character group variable is 1.

CONDITIONAL CODE - EXAMPLE 2 /* Combine summary statistics for */ /* group and total */ data sumstat (drop = &_grpvar set out outall(in=all %if &_grptyp = C and &_grplen = 1 %then %do; length tempgrp $ 2; tempgrp = &_grpvar; /* Assign total group value based */ /* on type */ %if &_grptyp = C %then %do; if all then tempgrp = 99 ; %else %if &_grptyp = N %then %do; if all then tempgrp = 99; TECHNIQUE 2 - GENERATED SAS CODE BASED ON VARIABLE VALUES The SAS macro function CALL EXECUTE exports data values directly to the macro facility for macro execution. Any generated SAS code is dumped into the input stack for execution after the DATA step is completed. In the following examples, global macro variables are created that contain information about the specific values of a data set variable. These global macro variable values are pieces of SAS code, based on the variable s actual values. The first step in this process is to create a temporary SAS data set that has one observation for each value of the variable &_grpval. An example of the code to create the variable values data set, called GRPVAL in the example, is shown below. CALL EXECUTE DATA SET CODE - EXAMPLE /* Create data set with all group */ /* values formatted to generate macro */ /* SAS code */ data grpval1; set grpval; length grprslt grpstat $ 8 grpfmt prtfmt $ 40 grpdef $ 70; /* Name of variable for group val */ grprslt= r trim(left(&_grpvar) /***************************/ /* Formatted group value */ /***************************/ %if &_grpfmt ^= %then %do; grpfmt = trim(left(put(&_grpvar,&_grpfmt)) %else %if &_grpfmt = %then %do; grpfmt=trim(left(&_grpvar) /* Name of variable with statistic*/ /* for group value */ grpstat= _ trim(left(&_grpvar) /* Text of statement to format */ /* group statistic for printing */ prtfmt=trim(left(grprslt)) = put( trim(left(grpstat)), 7.2) ; /* Text of PROC REPORT define */ /* statement */ grpdef = "define" trim(left(grprslt)) " / display right '-" trim(left(grpfmt)) "-' width=12"; VARIABLE VALUES DATA SET CODE - EXAMPLE /* Find all values of group variable */ /* in data set */ proc freq data=&_data noprint; tables &_grpvar / missing out=grpval drop=(count percent If the treatment group variable has two values (0 and 1), then a listing of the data set generated by the above example code is shown below. The variable values data set can be expanded into a CALL EXECUTE data set by generating new variables that are either parts of SAS statements or entire SAS statements, incorporating the values of a variable.

CALL EXECUTE DATA SET LISTING - EXAMPLE OBS TXGROUP GRPSTAT GRPRSLT GRPFMT PRTFMT GRPDEF 1 0 _0 r0 Placebo r0 = put(_0, 4.0) define r0 / display right '-Placebo-' width=12 2 1 _1 r1 Drug r1 = put(_1, 4.0) define r1 / display right '-Drug-' width=12 where TXGROUP gives the specific values of the group variable -- 0 and 1; GRPSTAT gives the names of the variables in the report macro with the summary statistic for each group value; GRPRSLT gives the names of the variables in the report macro with the formatted statistic for each group value; GRPFMT gives the names of the variables in the report macro with the formatted version of each group value; PRTFMT gives the statements in the report macro that format the summary statistic for each group value; and GRPDEF gives the PROC REPORT define statement in the report macro for each group value. The macros MAKELIST and MAKESTMT use the CALL EXECUTE data set and the CALL EXECUTE macro function to generate global macro variables. These global macro variables are then used as SAS code in instances where SAS code is dependent on the specific values of a variable. The macro MAKELIST concatenates a series of variables into a string and places them in a global macro variable. The macro MAKESTMT concatenates a series of SAS statements into a string and places them in a global macro variable. %MACRO MAKELIST GENERATE LIST OF VARIABLES /* Macro name : MAKELIST */ /* Purpose: Creates a macro variable */ /* that contains SAS code based on data*/ /* found in a driver data set using */ /* CALL EXECUTE. The SAS code is a */ /* list of values, not an entire SAS */ /* statement. */ /* Called by: General report macro */ /* Input: DSN-Name of driver data set */ /* CODEVAR-Name of variable in */ /* driver data set to be */ /* concatenated. */ /* Output: LISTVAR-Name of macro var */ /* that contains SAS code */ /* based on values of CODEVAR */ %macro makelist(dsn=, /*driver data set*/ codevar=,/*ds variable */ listvar= /*macro var */ %global &&listvar; %let &listvar = ; data _null_; set &dsn; call execute ( %let &listvar = &&&listvar left(trim(&codevar)) ; %mend makelist; %MACRO MAKESTMT GENERATE LIST OF SAS STATEMENTS /* Macro name : MAKESTMT */ /* Purpose: Creates a macro variable */ /* that contains SAS code based on data*/ /* found in a driver data set using */ /* CALL EXECUTE. The SAS code is a */ /* list of SAS statements. */ /* Called by: General report macro */ /* Input: DSN-Name of driver data set */ /* CODEVAR-Name of variable in */ /* driver data set to be */ /* concatenated. */ /* Output: STMTVAR-Name of macro var */ /* that contains SAS statements */ /* based on values of CODEVAR */ %macro makestmt(dsn=, /*driver data set*/ codevar=,/*data set var*/ stmtvar= /*macro var */ %global &&stmtvar; %let &stmtvar = ; data _null_; set &dsn; call execute ( %let &stmtvar = &&&stmtvar left(trim(&codevar)) %str(; %mend makestmt;

An example of a call to the macro MAKELIST in a general report macro is shown below. It generates a global macro variable &grplist, a list of result variables, one for each value of the treatment group variable. MAKELIST MACRO CALL - EXAMPLE %makelist(dsn=grpval1, codevar=grprslt, listvar=grplist) will generate the global macro variable &grplist with the value: &grplist = r0 r1 An example of a call to the macro MAKESTMT in a general report macro is shown below. It generates a global macro variable &define, a series of PROC REPORT DEFINE statements for the result variable for each value of the treatment group variable. MAKESTMT MACRO CALL - EXAMPLE %makestmt(dsn=grpval1, codevar=grpdef, stmtvar=define) will generate the global macro variable &define with the value: &define = define r0 / display right '-Placebo-' width=12; define r1 / display right '-Drug-' width=12; The global macro variables &grplist and &define, can be used to supply SAS code in the general report macro as sections of code in a PROC REPORT step. &Grplist gives the list of the names of variables associated with each value of the group variable, and it is inserted as part of a COLUMNS statement. &Define gives the text of each DEFINE statement for each variable listed in &grplist. MACRO VARIABLES AS SAS CODE - EXAMPLE proc report data=out nowd headline headskip; columns vartitl varcat &grplist testname testpval; define vartitl / group Variable ; define varcat / group ; &define define testname / display Test ; define testpval / display p-value ; break after vartitl/skip; TECHNIQUE 3 - CONDITIONALLY GENERATED SAS CODE BASED ON VARIABLE VALUES Code can be generated conditionally based on the values of a variable or, as in the example given below, based on the number of values of a variable. In this example, the macro variable &numgrps gives the number of values for the treatment group variable. This number is determined by using new 6.12 data step functions to get the number of observations in the SAS data set GRPVAL1, created in the preceding section. The number of treatment groups in this example report macro will dictate the statistical test to be used for data analysis. VALUE-BASED CONDITIONAL CODE - EXAMPLE %let grpval1 = grpval1; %let dsid = %sysfunc(open(&grpval1,i) %let numgrps=%sysfunc(attrn(&dsid,nobs) %let rc = %sysfunc(close(&dsid) %if &numgrps >= 3 %then %do; <<code to perform an ANOVA>> %else %if &numgrps = 2 %then %do; <<code to perform a T-TEST>> %else %if &numgrps <= 1 %then %do; <<warning, only 1 group, no test done>> CONCLUSION Using these programming techniques, we have programmed several generalized SAS macros that produce standard reports used in clinical drug studies. Examples of standard clinical study reports that have been generalized include Adverse Event Severity and Relationship to Treatment and Statistical Comparison of Treatment Groups at Baseline. The names of report variables found in a specific clinical study s data are supplied as input parameters to these macros, and the resulting SAS programs generated by these macros are customized to the specific characteristics and values of each study s data. To run a standard report using a general report macro, all we need to do is set up the study-specific front end. The study data are modified as needed prior to input to the general report macro, and the relevant variable and data set names are defined as macro variables. These generalized report programming techniques using data-driven SAS code have the advantages of reducing programming time and increasing programming accuracy. Although the general report macros are more complex initially to program and validate, they save much time over the long term if they are used frequently. Further, these general macros can be validated for accuracy only once because they don t need to be modified every time they are used for different studies.

ACKNOWLEDGEMENTS The authors would like to acknowledge Elizabeth Reed, Paradigm Shift, L.L.C., for her invaluable help in the development and testing of the report macros and for her insightful comments while editing this manuscript. SAS is a registered trademark or trademarks of SAS Institute Inc. in the USA and other countries. indicates USA registration. REFERENCES Bahler, Caroline (1998). New Data Step Functions in SAS 6.12 Data Set and Variable Functions. Proceedings of the Sixth Annual Conference of the SouthEast SAS Users Group. USA SAS Institute Inc. (1997), SAS Macro Language Reference, First Edition, Cary, NC: SAS Institute Inc. What s New In Release 6.12. SAS Institute Technical Support web page (1999), http://www.sas.com/service/techsup/wn612/wnbase.htm Whitlock, H. Ian (1994). An Introduction to SAS Macro. Proceedings of the Second Annual Conference of the SouthEast SAS Users Group. USA. CONTACT INFORMATION Kathy Hardis Fraeman A.K. Analytic Programming, L.L.C. 16816 Ethelwood Terrace Olney, MD 20832 (301) 570-4495 fraeman@his.com Karen G. Malley Malley Research Programming, Inc. 1840 Greenplace Terrace Rockville, MD 20850 tel: (301) 424-8670 fax: (301) 424-8671 kgmalley@erols.com