PharmaSUG 2012 Paper CC13

Similar documents
Data Annotations in Clinical Trial Graphs Sudhir Singh, i3 Statprobe, Cary, NC

PharmaSUG Paper TT10 Creating a Customized Graph for Adverse Event Incidence and Duration Sanjiv Ramalingam, Octagon Research Solutions Inc.

Effective Forecast Visualization With SAS/GRAPH Samuel T. Croker, Lexington, SC

Creating Forest Plots Using SAS/GRAPH and the Annotate Facility

INTRODUCTION TO THE SAS ANNOTATE FACILITY

A Generalized Procedure to Create SAS /Graph Error Bar Plots

Tips for Producing Customized Graphs with SAS/GRAPH Software. Perry Watts, Fox Chase Cancer Center, Philadelphia, PA

It s Not All Relative: SAS/Graph Annotate Coordinate Systems

IMPROVING A GRAPH USING PROC GPLOT AND THE GOPTIONS STATEMENT

Coders' Corner. Paper ABSTRACT GLOBAL STATEMENTS INTRODUCTION

Taming the Box Plot. Sanjiv Ramalingam, Octagon Research Solutions, Inc., Wayne, PA

SUGI 29 Posters. Paper A Group Scatter Plot with Clustering Xiaoli Hu, Wyeth Consumer Healthcare., Madison, NJ

Tips and Tricks in Creating Graphs Using PROC GPLOT

THE IMPACT OF DATA VISUALIZATION IN A STUDY OF CHRONIC DISEASE

Tips to Customize SAS/GRAPH... for Reluctant Beginners et al. Claudine Lougee, Dualenic, LLC, Glen Allen, VA

How to annotate graphics

Multiple Forest Plots and the SAS System

A Plot & a Table per Page Times Hundreds in a Single PDF file

SparkLines Using SAS and JMP

Top Award and First Place Best Presentation of Data Lan Tran-La. Scios Nova, Inc. BLOOD PRESSURE AND HEART RATE vs TIME

Using Annotate Datasets to Enhance Charts of Data with Confidence Intervals: Data-Driven Graphical Presentation

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

The GSLIDE Procedure. Overview. About Text Slides CHAPTER 27

Innovative Graph for Comparing Central Tendencies and Spread at a Glance

SAS Graphs in Small Multiples Andrea Wainwright-Zimmerman, Capital One, Richmond, VA

ABSTRACT INTRODUCTION SESUG RV

Create Flowcharts Using Annotate Facility. Priya Saradha & Gurubaran Veeravel

Modifying Graphics in SAS

Displaying Multiple Graphs to Quickly Assess Patient Data Trends

Chapter 1 Introduction. Chapter Contents

Figure 1. Paper Ring Charts. David Corliss, Marketing Associates, Bloomfield Hills, MI

Paper S Data Presentation 101: An Analyst s Perspective

The GANNO Procedure. Overview CHAPTER 12

A SAS Macro to Generate Caterpillar Plots. Guochen Song, i3 Statprobe, Cary, NC

A Juxtaposition of Tables and Graphs Using SAS /GRAPH Procedures

A Stand-Alone SAS Annotate System for Figure Generation Brian Fairfield-Carter, PRA International, Victoria, BC

SAS/GRAPH : Using the Annotate Facility

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

Arthur L. Carpenter California Occidental Consultants

Arthur L. Carpenter California Occidental Consultants, Oceanside, California

The Plot Thickens from PLOT to GPLOT

Making Presentations More Fun with DATA Step Graphics Interface (DSGI) Hui-Ping Chen, Eli Lilly and Company, Indianapolis, Indiana

Want Quick Results? An Introduction to SAS/GRAPH Software. Arthur L. Carpenter California Occidental Consultants

Multiple Graphical and Tabular Reports on One Page, Multiple Ways to Do It Niraj J Pandya, CT, USA

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

Data Driven Annotations: An Introduction to SAS/GRAPH s Annotate Facility

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

SAS Graph: Introduction to the World of Boxplots Brian Spruell, Constella Group LLC, Durham, NC

The GTESTIT Procedure

Paper SIB-096. Richard A. DeVenezia, Independent Consultant, Remsen, NY

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

* builds the RGB color string from the color. * reads the red, green; and blue values for. * constructs an ANNOTATE dataset by

Fly over, drill down, and explore

Picturing Statistics Diana Suhr, University of Northern Colorado

Converting Annotate to ODS Graphics. Is It Possible?

How to Make an Impressive Map of the United States with SAS/Graph for Beginners Sharon Avrunin-Becker, Westat, Rockville, MD

Presentation Quality Graphics with SAS/GRAPH

Controlling Titles. Purpose: This chapter demonstrates how to control various characteristics of the titles in your graphs.

... WHERE. AnnotaI8 Data.S... XSYS & YSYS. Harie Annotate: How Not to Lose Your Head When Enhancing BAS/GRAPH output

ODS LAYOUT is Like an Onion

FILLPATTERNS in SGPLOT Graphs Pankhil Shah, PPD, Morrisville, NC

ABC s of Graphs in Version 8 Caroline Bahler, Meridian Software, Inc.

SAS/GRAPH Introduction. Winfried Jakob, SAS Administrator Canadian Institute for Health Information

USING SAS PROC GREPLAY WITH ANNOTATE DATA SETS FOR EFFECTIVE MULTI-PANEL GRAPHICS Walter T. Morgan, R. J. Reynolds Tobacco Company ABSTRACT

Generating Participant Specific Figures Using SAS Graphic Procedures Carry Croghan and Marsha Morgan, EPA, Research Triangle Park, NC

Run your reports through that last loop to standardize the presentation attributes

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

ABC Macro and Performance Chart with Benchmarks Annotation

SAS: Proc GPLOT. Computing for Research I. 01/26/2011 N. Baker

Using ANNOTATE MACROS as Shortcuts

Annotate Dictionary CHAPTER 11

Pete Lund Looking Glass Analytics, Olympia, WA

And Now, Presenting... Presentation Quality Forecast Visualization with SAS/GRAPH Samuel T. Croker, Independent Consultant, Lexington, SC

Using SAS/GRAPH Software to Create Graphs on the Web Himesh Patel, SAS Institute Inc., Cary, NC Revised by David Caira, SAS Institute Inc.

Creating Maps in SAS/GRAPH

Clip Extreme Values for a More Readable Box Plot Mary Rose Sibayan, PPD, Manila, Philippines Thea Arianna Valerio, PPD, Manila, Philippines

A SAS Macro Utility to Modify and Validate RTF Outputs for Regional Analyses Jagan Mohan Achi, PPD, Austin, TX Joshua N. Winters, PPD, Rochester, NY

Using Big Data to Visualize People Movement Using SAS Basics

Internet, Intranets, and The Web

Data Edit-checks Integration using ODS Tagset Niraj J. Pandya, Element Technologies Inc., NJ Vinodh Paida, Impressive Systems Inc.

USING PROC GMAP AND DRILL-DOWN GRAPHICS FOR DATA QUALITY ASSURANCE Meghan Arbogast, Computer Sciences Corporation, Corvallis, OR

Create a Format from a SAS Data Set Ruth Marisol Rivera, i3 Statprobe, Mexico City, Mexico

Correcting for natural time lag bias in non-participants in pre-post intervention evaluation studies

Creating Complex Graphics for Survival Analyses with the SAS System

SAS/GRAPH and ANNOTATE Facility More Than Just a Bunch of Labels and Lines

Paper Abstract. Introduction. SAS Version 7/8 Web Tools. Using ODS to Create HTML Formatted Output. Background

Developing Graphical Standards: A Collaborative, Cross-Functional Approach Mayur Uttarwar, Seattle Genetics, Inc., Bothell, WA

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

Chapter 13 Introduction to Graphics Using SAS/GRAPH (Self-Study)

Coders' Corner. Scaling Mount GCHART: Using a MACRO to Dynamically Reset the Scale Nina L. Werner, Dean Health Plan, Inc., Madison, WI.

A Dynamic Imagemap Generator Carol Martell, Highway Safety Research Center, Chapel Hill, NC

SAS (Statistical Analysis Software/System)

ABSTRACT. The SAS/Graph Scatterplot Object. Introduction

SAS (Statistical Analysis Software/System)

Have SAS Annotate your Blank CRF for you! Plus dynamically add color and style to your annotations. Steven Black, Agility-Clinical Inc.

Macros for creating a custom report of figures

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

My Reporting Requires a Full Staff Help!

Making an RTF file Out of a Text File, With SAS Paper CC13

Regaining Some Control Over ODS RTF Pagination When Using Proc Report Gary E. Moore, Moore Computing Services, Inc., Little Rock, Arkansas

Transcription:

PharmaSUG 2012 Paper CC13 Techniques for Improvising the Standard Error Bar Graph and Axis Values Completely Through SAS Annotation Sunil Kumar Ganeshna, PharmaNet/i3, Pune, India Venkateswara Rao, PharmaNet/i3, Pune, India ABSTRACT This paper introduces the multiple challenges and several useful techniques for enhancing SAS/GRAPH output when creating plots with standard error bars and symbols of the least square means/mean and enhancing multiple x-axis values with uneven intervals. The macro presented in this paper utilizes the techniques of data manipulation, SAS annotation, markers and fonts, plot statement, axis statement, symbol and legend statements; this single macro call generates an annotated dataset that is utilized to create an Error bar graph with multiple axis values. INTRODUCTION There are several methods for drawing standard error bars onto a mean plot. The most common method is to use the options INTERPOL=STDJT or INTERPOL=HILOJT in the SYMBOL statement, and each has its own drawbacks when used for displaying the mean data values with symbols. If the VALUE and HEIGHT options are applied in the SYMBOL statement, you are unable to annotate the mean values with symbols, but all of the individual data values are plotted along the standard error bars. In order to overcome the drawbacks with the above-mentioned options, we created mean plots displaying standard error bars and symbols for the means by annotation. For displaying the multiple x-axis values, we can use the TICK option in the AXIS statement, but still this may cause a problem for uneven intervals. Challenges involved in this task: 1) Creating error bars with special symbols like inverted triangles, or triangles that are fully filled with color. 2) Jittering the axis values to avoid overlapping of the treatments. 3) Creating two different line types for a single treatment between the visits, showing the differentiation of the visits or switching of the treatments. 4) Creating multiple x-axis values with uneven intervals with their corresponding text. 5) Avoiding unwanted tick marks and placing them only at the respective positions. 6) Creating a y-axis range with uniform intervals for multiple outputs. TECHNIQUES A macro was created to resolve all of the above challenges. 1) This macro creates two annotated datasets. One annotated dataset is used to create all of the error bars for each treatment with respect to each visit using different symbol fonts. 2) This data set is manipulated to create two different line types for a specified treatment, varying between the visits to differentiate visits of a particular treatment. (Check the output for black and blue colored lines how the line types are differing for each of these treatments). 3) Special symbols were used rather than a simple hyphen to differentiate the upper and lower limits.(check for Black and Red color symbols in the output in Appendix 1 4) The second annotated data set is created to capture the x-axis interval values at multiple levels i.e., each row represents different levels, with a text description at the beginning of the row. For example, the first row describes the month, the second row displays its corresponding visit, and the third row displays the week (see the graph x-axis values in Appendix 1). 5) One more macro is involved to calculate the y-axis range with uniform intervals. This macro takes care of the uniform distribution of the y-axis values. and is useful if we are creating multiple outputs from a single program, rather than calculating the minimum and maximum value for each plot every time. 1

CONCLUSION SAS ANNOTATION is a powerful and productive tool in SAS/GRAPH and should be fully examined and exploited. In this paper, we have shown how to use the annotation facility to create a macro that will resolve all the above challenges and create the error bar graph. The advantages of this macro are 1) It addresses all the above challenges while making the code intuitive. 2) A single macro call can generate multiple graphs that take care of all of the necessary requirements without much effort. 3) Portions of the macro can also be used as pieces of code, if required. For example, annotation is only needed for defining the axis intervals- it s not required for the error bars. 4) This macro can be used as a reference for other graphs, and also for creating annotation datasets. A complete description of the macro is found in Appendix 2, and each parameter is defined in Appendix 2, using the graph as an example REFERENCES SAS/GRAPH Software: version 9.1.3, SAS Institute Inc., Cary NC SAS/Graph help online documentation: Version 9, SAS Institute Inc,, Cary NC. Tired of Defining Axis Scale for SAS Graphs? A Solution with an Automatic Optimizing Approach. Don (Dongguang) Li, NCIC-CTG at Queen s University, Kingston, ON, Canada. PharmaSUG 2003 conference proceedings. ACKNOWLEDGMENTS Thanks to Vijay Moolaveesala and Nancy Brucken for their suggestions on this paper. CONTACT INFORMATION Please send your comments, questions, and inquiries to: Name: Sunil Kumar Ganeshna, Address: PharmaNet/i3, Commerzone, 6th Floor, Building No 4, Yerwada, Pune, India. E-mail: skumar2@pharmanet-i3.com sunilganeshna@gmail.com Name: Venkateswara Rao Ch.,M.Sc (Statistics) Address: PharmaNet/i3, Commerzone, 6th Floor, Building No 4, Yerwada, Pune, India. E-mail: verao@pharmanet-i3.com venkibhu@aol.com 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. Other brand and product names are trademarks of their respective companies. 2

APPENDIX 1 3

APPENDIX 2 MACRO PARAMETERS Name Type Default Description and Valid Values Indata Required Name of the input dataset The input dataset must contain the following variables Grouping variable for example, treatment. 1) X-axis variable that contains the values plotted on the x- axis. 2) Estimate variable that contains the point estimates (for example mean is the point estimate if the y-axis in the graph is mean+/-std, Lsmeans is the point estimate if the y-axis is Lsmeans+/-se based on the requirements). 3) Upper upper limit of the estimates. 4) Lower lower limit of the estimates. These 5 variables are mandatory for running this macro. Group_var Optional Null Name of the grouping variable in the input data set. This should be numeric. X_axis Required Name of the x-axis variable in the input data set. This should be numeric. Gap_bars Required To avoid the overlapping of bars of distinct levels of classification variable at a value of X. Specify the margins separated by ",". If the classification variable contains 4 levels, then the gap_bars should be "0.1, 0.2,0.3,0.4". The values 0.1, 0.2, 0.3 have to be adjusted based on the range of the x-axis. The number of values specified in "gap_bars" should be equal to the number of levels in the grouping variable. Estimate Required Numeric Value Name of the variable containing the values of point estimates for e.g. mean, lsmeans. Upper Required Numeric Name of the variable containing the values of upper limits of the estimates. Value Lower Required Numeric Name of the variable containing the values of lower limits of the estimates. Value Col_sym Required black Name of the colors to be displayed for the symbols in the graph. Sym_est Required Specifies the plot symbols for the data points. For example, if there are 4 treatments, each treatment has to be represented by a separate symbol. If Treatment A is represented by an inverted triangle, the symbol D displays that inverted triangle in the specified font. Font_sym_ est Required Name of the font to be used for the symbols that we specified in the sym_est parameter. For example, the MARKER font was used to display inverted triangles for Treatment A. 4

The following site lists many fonts and markers that can be used in the SYMBOL statement: http://support.sas.com/documentation/cdl/en/graphref/63022/html/default /viewer.htm#font-font-lists.htm line_type Required 1 Sometimes, the lines in the graph may be dashed lines with different spaces and sizes. This parameter is used to specify the type of line for every category in the group variable. Default is "1" (a straight line). Sym_lim Required This parameter is used to define the symbols for both the upper and lower limits. For example if (hyphen) is used, then the corresponding symbol for this is J. Font_sym_l imits Gp_visit_li ne Required Name of the fonts to be used for the symbols that we specified in the sym_lim parameter. Since we have defined J as the respective symbol, the corresponding font for this is MUSIC. Optional Null Required if we want to differentiate the line type for a specified group_var (ex: treatment) from a particular visit to the last visit. For ex: for treatment 2, we want a dashed line from visit 3 to the end, so this should be specified as 2 3 2 (treatment visit line type). If this needs to cover multiple treatments, then the delimiter is a comma.if we want to differentiate the line type for two treatments then they should be separated by comma like 2 3 2, 3 5 20 (for treatment 3 the line type should change from visit 5 to end.) Rows_xaxis Required Sometimes the x-axis value labels require multiple lines. For example, the x-axis value labels may contain both visit and month. In this case, the value of rows_xaxis is 3. Labels_row s_xaxis Required Text to be printed for the x-axis values in multiple rows. See the graph for x-axis values and their corresponding left side text. Formats Required Format to be applied to the x-axis values. X_axis_lab el Optional Label for the x-axis. Zero_yaxis Required no Sometimes a reference line corresponding to the "0" on y-axis is needed for graphs of change from baseline. The valid values for this parameter are "yes" and "no". Pos_x_valu es Required The x-axis values are displayed with the annotation facility. If the placement of the legend changes, then the position values of the x-axis will change automatically. The user has to determine the values, and then manually check to get the proper alignment of x-axis values. -------------------------------------------------------------------------------- Usage Notes: -------------------------------------------------------------------------------- Typical Macro Call(s) and Description: 5

This macro will also create the following internal macro variables: max_y --- Maximum value on y-axis min --- Minimum value on y-axis interval --- Difference between major tick marks on the y-axis. max_x --- maximum value on x-axis min_x --- minimum value on x-axis Use these parameters in the corresponding axis statements. %macro Error_Graph(indata=, group_var=, x_axis=, gap_bars=, estimate=, upper=, lower=, col_sym=, sym_est=, font_sym_est=, line_type=, gp_visit_line=, sym_lim=, font_sym_lim=, rows_xaxis=, labels_rows_xaxis=, formats=, xaxis_label=, zero_yaxis=, pos_x_values=); %if %sysfunc(exist(anno)) %then %do; /*Dropping the ANNO dataset to avoid the problems on appending the datasets again and again*/ PROC SQL; DROP TABLE anno; QUIT; %let height_symbol=2.5;%let height_line=0.3; %if &group_var ne %then %do; %else %do; /* Creating a dataset with distinct categories of Group Variable */ PROC SORT DATA=&indata(KEEP=&group_var) OUT=group nodupkey; BY &group_var; /*Assigning the distinct categories in Group variable to macro variable to create one Annotation dataset for each category and also Number of Distinct Categories*/ DATA group; SET group; CALL SYMPUT (CATT("group",_n_),PUT(&group_var,best.)); CALL SYMPUT("no_groups",PUT(_n_,best.)); Run; 6

/*Fixing the values of the macro variables "no_groups" and "group1" when the Grouping variable is missing or null*/ %let no_groups=1; %let group1=1; DATA &indata; Set &indata; group_var=1; /*Creating annotation dataset for every single category in the grouping variable*/ %Do i = 1 %to &no_groups; DATA _null_; /*Assigning the gap between bars, color of symbol, symbol and font for a symbol, Symbl and font for both the limits*/ CALL SYMPUT("gap",SCAN("&gap_bars",&i,",")); CALL SYMPUT("color", SCAN("&col_sym",&i,",")); call symput("sym_estimate", SCAN("&sym_est",&i,",")); CALL SYMPUT("font_sym_estimate", SCAN("&font_sym_est",&i,",")); CALL SYMPUT("sym_limits", SCAN("&sym_lim",&i,",")); CALL SYMPUT("font_sym_limits", SCAN("&font_sym_lim",&i,",")); CALL SYMPUT("type", SCAN("&line_type",&i,",")); %if &color= %then %let color=black; %if &type= %then %let type=1; /*Creating a symbol statement for every category in the grouping variable*/ %if &group_var ne %then %do; SYMBOL&i VALUE=&sym_estimate FONT=&font_sym_estimate LINE=&type CV=&color INTERPOL=join HEIGHT=0.01; %else %do; SYMBOL&i VALUE=&sym_estimate FONT=&font_sym_estimate CV=&color HEIGHT=0.01; /*Creating macro variables for the required variables */ DATA _null_; SET &indata; CALL SYMPUT(cats("original_x",_n_),put(&x_axis,best.)); Run; CALL SYMPUT(CATS("x",_n_),PUT(&x_axis+&gap,best.)); CALL SYMPUT(CATS("est",_n_), PUT(&estimate,best.)); CALL SYMPUT(CATS("upper_limit",_n_), PUT(&upper,best.)); CALL SYMPUT(CATS("lower_limit",_n_), PUT(&lower,best.)); CALL SYMPUT("no_visits", PUT(_n_,best.)); WHERE &group_var=&&group&i; /*Creating annotated dataset for drawing the error bars with special symbols and for connecting each error bar*/ DATA anno_%sysfunc(left(&&group&i)); FORMAT x 10.5; LENGTH function $20. style $20. text $20. color $10.; RETAIN xsys ysys "2" hsys "3" color "&color";; %if &group_var ne %then %do; group_var=&&group&i; 7

%else %do; Group_var=1; %do j = 1 %to &no_visits; %if &j < &no_visits %then %do; data="estimate_line";original_x=&&original_x&j;x=&&x&j;y=&&est&j;function="mo VE";size=&height_line;line=&type; OUTPUT; %let k=%eval(&j+1); data="estimate_line";original_x=&&original_x&k;x=&&x&k;y=&&est&k;function="dr AW"; OUTPUT;size=&height_line;line=&type; OUTPUT; data="estimate";original_x=&&original_x&j;x=&&x&j;y=&&est&j;function="symbol" ;text="&sym_estimate";size=&height_symbol;style="&font_sym_estimate";when="a" ; OUTPUT; data="limits_join";original_x=&&original_x&j;x=&&x&j;y=&&lower_limit&j; function="move";size=&height_line;line=1; OUTPUT; data="limits_join";original_x=&&original_x&j;x=&&x&j;y=&&upper_limit&j; function="draw";size=&height_line;line=1; OUTPUT; data="lower";original_x=&&original_x&j;x=&&x&j;y=&&lower_limit&j;function="sy MBOL";size=&height_symbol;text="&sym_limits";style="&font_sym_limits";when="A "; OUTPUT; data="upper";original_x=&&original_x&j;x=&&x&j;y=&&upper_limit&j;function="sy MBOL";size=&height_symbol;text="&sym_limits";style="&font_sym_limits";when="A "; OUTPUT; %else %do; data="limits_join";original_x=&&original_x&j;x=&&x&j;y=&&lower_limit&j; function="move"; size=&height_line;line=1; OUTPUT; data="limits_join";original_x=&&original_x&j;x=&&x&j;y=&&upper_limit&j; function="draw"; size=&height_line;line=1; OUTPUT; data="estimate";original_x=&&original_x&j;x=&&x&j;y=&&est&j;function="symbol" ;text="&sym_estimate";style="&font_sym_estimate";when="a"; size=&height_symbol; OUTPUT; data="lower";original_x=&&original_x&j;x=&&x&j;y=&&lower_limit&j;function="sy MBOL";text="&sym_limits";style="&font_sym_limits";when="A"; size=&height_symbol; OUTPUT; data="upper";original_x=&&original_x&j;x=&&x&j;y=&&upper_limit&j;function="sy MBOL"; text="&sym_limits";style="&font_sym_limits";when="a"; size=&height_symbol; OUTPUT; run; %if %sysfunc(exist(anno)) %then %do; /*Appending the annotation datasets of every category in group variable to the dataset ANNO*/ PROC APPEND DATA=anno_%sysfunc(LEFT(&&group&i)) BASE=Anno; %else %do; 8

DATA ANNO; SET anno_%sysfunc(left(&&group&i)); PROC SORT DATA=&indata(KEEP=&x_axis) OUT=xaxis(RENAME=(&x_axis=x)) NODUPKEY; BY &x_axis; DATA anno_axis1; LENGTH text $100. data $20.; RETAIN hsys "1" size 2.5; SET xaxis(keep=x in=a) xaxis(keep=x in=b) end=eof; if a then do; data="tick";xsys="2";ysys="1";text="i";y=0;position="5";style="simplex"; OUTPUT; else if b then do; %do k=1 %to &rows_xaxis; format=catt(scan("&formats",&k,","),".");data="x_value";size=3;xsys="2";ysys= "5";text=left(putn(x,format)); y=&pos_x_values- 2.5*&k;position="5";style="simplex"; OUTPUT; if eof then do; %do k=1 %to &rows_xaxis; data="x_value_label";size=3;xsys="1";ysys="5";text=scan("&labels_rows_xaxis", &k,",") ;x=0;y=&pos_x_values-2*&k;position="5";style="simplex"; OUTPUT; data="label";size=3;xsys="2";ysys="5";text="&xaxis_label";x=50;xsys="1";y=&po s_x_values-2.5*(&k+1);position="5";style="simplex"; OUTPUT; DATA anno; SET anno anno_axis1; %global max_y; /*Finding the maximum value for the Y-axis to decide the number of intervals to be shown in the Y-axis*/ PROC SQL NOPRINT; SELECT MIN(y),MAX(y),MIN(group_var) INTO :min_y,:max_y,:useless FROM anno WHERE group_var >=0; QUIT; %put &min_y; %MACRO scale (max); %if &max=0 %then %do; %let max=5; DATA _null; unit=&max/10; grade=floor(log10(unit)); sunit=unit/(10**grade); if sunit<sqrt(2) then interval=10**grade*1; else if sunit<sqrt(10) 9

then interval=10**grade*2; else if sunit<sqrt(50) then interval=10**grade*5; else interval=10**grade*10; maxscale=ceil(&max/interval)*interval; %global maxscale interval; CALL SYMPUT ("maxscale",left(put(maxscale,best.))); CALL SYMPUT ("interval",left(put(interval,best.))); run; %MEND scale; %scale(&max_y); %put &maxscale; %put &interval; DATA e1; do l = -&maxscale to &maxscale by &interval; l1=lag(l); y=&min_y; OUTPUT; DATA _null_; SET e1; If "&zero_yaxis"="yes" then do; if y <0 then do; if l1<y; CALL SYMPUTX("min",l1,"g"); else do; if l1=0; CALL SYMPUTX("min",l1,"g"); else do; if l1<y; CALL SYMPUTX("min",l1,"g"); Run; PROC SORT DATA=anno OUT=plot_data; BY group_var x; WHERE data eq "estimate" and group_var ne.; DATA _NULL_; CALL SYMPUT("commas",COUNT("&gp_visit_line",",")+1); DATA plot_data; SET plot_data; %if &gp_visit_line ne %then %do; %do l= 1 %to &commas; %let word=%sysfunc(scan(&gp_visit_line,&l,",")); %let one=%sysfunc(scan(&word,1)); %let two=%sysfunc(scan(&word,2)); if group_var = &one and original_x>&two then DELETE; 10

DATA anno; SET anno; %if &gp_visit_line ne %then %do; %do l= 1 %to &commas; %let word=%sysfunc(scan(&gp_visit_line,&l,",")); %let one=%sysfunc(scan(&word,1)); %let line=%sysfunc(scan(&word,3)); %let two=%sysfunc(scan(&word,2)); if group_var = &one and original_x=&two and data="estimate_line" and funtion="move" then line=&line; else if group_var = &one and original_x>&two and data="estimate_line" then line=&line; %if &group_var = %then %do; DATA anno; SET anno; WHERE data ne "estimate_line"; %global min_x max_x; PROC SQL NOPRINT; SELECT MIN(x),MAX(x),MAX(group_var) INTO :min_x,:max_x,:useless FROM anno WHERE group_var>=0; QUIT; %mend Error_Graph; Sample macro call and steps to pass the proc gplot. %Error_Graph(indata=indata, group_var=trtsort, x_axis=plmosrnd, gap_bars=%str(-0.1,-0.2,0.15,0.2), estimate=estimate, upper=upper, lower=lower, col_sym=%str(blue,green,red,black), sym_est=%str(c,d,u,w), font_sym_est= %str(marker,marker,marker,marker), line_type=%str(1,1,1,1), gp_visit_line=%str(1 2 2,7 6 20), sym_lim=%str(j,j,v,v), font_sym_lim=%str(music,music,marker,marker), rows_xaxis=3, labels_rows_xaxis=%str(month,week,visit), formats=%str(best,wek,visit), xaxis_label=, zero_yaxis=no, pos_x_values=14); *Origin can be changed according to user s requirement; GOPTIONS RESET=all; GOPTIONS RESET=goptions DEVICE = png CBACK = white CTEXT = black noborder TARGET=png XMAX=10 in YMAX=7.5 in FTEXT = simplex FTITLE = simplex HTEXT = 2.1 VSIZE=7in HSIZE=10 in Htitle=2 COLORS = (black) GSFLEN=80 GUNIT = pct 11

display GSFMODE = replace ; SYMBOL1 COLOR =blue HEIGHT=0.0001 FONT="marker" V=C WIDTH=0.5 I=j line=20; SYMBOL2 COLOR = green HEIGHT=0.0001 FONT="marker" v=d WIDTH=0.5 I=j ; SYMBOL3 COLOR =red HEIGHT=0.0001 FONT="marker" v=u WIDTH=0.5 I=j ; SYMBOL4 COLOR =black HEIGHT=0.0001 WIDTH=0.5 FONT="marker" V=W I=j ; AXIS1 MAJOR=none VALUE=none MINOR=none ORDER=(&min_x to &max_x BY %sysevalf(&max_x- &min_x)) LABEL=(angle=90 j=c " ") OFFSET=(5,3); AXIS2 MINOR=none ORDER=(&min to %sysevalf(&max_y+&interval) BY &interval) LABEL=(angle=90 rotate=360 "LSmean+/-SE") OFFSET=(2,2); LEGEND1 MODE = protect ACROSS = 4 NOFRAME VALUE= (h=2.4 justify = left) POSITION = (bottom center inside) SHAPE = symbol(6,2.5) OFFSET =(0,0) LABEL = none ; TITLE1 "Plot of Error Bar by Each Treatment and Visit"; FOOTNOTE1 "Graph Created Through Annotation"; OPTIONS ORIENTATION =landscape PS=64 ; ODS listing close; ODS rtf FILE="&pharmasug/rptnm.rtf"; PROC GPLOT DATA=plot_data; PLOT y*x=group_var / HAXIS=axis1 ANNOTATE=anno VAXIS=axis2 LEGEND=legend1; FORMAT GROUP_VAR TRT. ; QUIT; ODS rtf close; ODS listing; 12