/**************************************************************************************************************************** CODE NAME : waterfall plot.sas OUTPUT NAME : (1) waterfall plot_single-panel.png ; (2) waterfall plot_multi-panel.png DESCRIPTION : Waterfall Plot for Tumor Size Change from Baseline (%) SOFTWARE/VERSION : SAS version 9.4 (TS1M5) WRITTEN BY : Ningying Wu DATE CREATED : Feb 2019 SUPPORTED BY : Siteman Cancer Center | Washington University School of Medicine ****************************************************************************************************************************/ ods noproctitle; ods listing; ods html ; ods graphics on; options label nodate number mlogic mprint symbolgen; %let path =X:\ningying\SAS-graphs\online example; /*path for output image*/ %let image1=waterfall plot_single-panel; /*name for output image*/ %let image2=waterfall plot_multi-panel; /*name for output image*/ /*****************************************************************************************/ /***** Part I *****/ /***** simulate a tumor response data *****/ /***** *****/ /*****************************************************************************************/ data Sim_Tumor; do PatientID = 101 to 110; Tx_Group = "Treatment A"; /*Poor Drug*/ Tumor_Size_Change = ranuni(111)*1.5 - 0.5; output; end; do PatientID = 211 to 220; Tx_Group = "Treatment B"; /*Good Drug*/ Tumor_Size_Change = ranuni(111)*1.2 - 0.95; output; end; run; data Sim_Tumor; set Sim_Tumor; if Tumor_Size_Change <= -0.3 then Response = "PR" ; else if Tumor_Size_Change >= 0.2 then Response = "PD" ; else Response = "SD" ; If PatientID = 212 then /*generate a CR*/ do; Tumor_Size_Change = -1 ; Response = "CR" ; end; format Tumor_Size_Change percentN8.2 ; Label Tumor_Size_Change= "Tumor Size Change (%)"; run; /*end: data simulation*/ /*Sort data by Tumor size change*/ proc sort data = Sim_Tumor; by descending Tumor_Size_Change; run; /*Using dataset waterfall_plot as the source for the format*/ data waterfall_plot ; set Sim_Tumor; Start = _N_; rename PatientID = Label; fmtname = "Descending_by_Change"; run; proc format CNTLIN=waterfall_plot ; run; proc print data=waterfall_plot ; run; /******************************************************************************/ /***** Part II *****/ /***** Image 1 waterfall plot (single panel) *****/ /***** *****/ /******************************************************************************/ ods listing gpath="&path\" ; ods graphics / reset outputfmt=png border=off imagename="&image1"; title font="Arial" height=12pt COLOR=Black j=c "Waterfall Plot" ; title2 font="Arial" height=8pt COLOR=GRAY j=c "(The Graph Features Can Be Customized If Needed)"; proc sgplot data=waterfall_plot; format Start Descending_by_Change.; /*format the order of change% with Patient ID*/ styleattrs datacolors=(lightgray lightgreen lightorange lightred) datacontrastcolors=(lightgray lightgreen lightorange lightred) ; refline 0.2 / axis=y lineattrs=(pattern=shortdash) label="PD: (*ESC*){unicode '2265'x} +20%" LABELPOS= auto LABELATTRS=(family="Arial" size=8pt weight=NORMAL) ; refline -0.3 / axis=y lineattrs=(pattern=shortdash)label="PR: (*ESC*){unicode '2264'x} -30%" LABELPOS= auto LABELATTRS=(family="Arial" size=8pt weight=NORMAL) ; vbar Start / response=Tumor_Size_Change group=Response baseline=0 transparency=0.2; xaxis label="Patient ID" LABELATTRS=(family="Arial" size=10pt weight=bold) VALUEATTRS=(family="Arial" size=10pt weight=NORMAL) ; yaxis label="RECIST: Tumor Size Change from Baseline (%)" values=(-1 to 1 by 0.2) VALUEATTRS=(family="Arial" size=10pt weight=NORMAL) LABELATTRS=(family="Arial" size=10pt weight=bold) ; keylegend /noBORDER location=inside position=bottomleft across=1 VALUEATTRS=(family="Arial" size=10pt weight=NORMAL) title=''; run; title; quit; ods graphics off; /******************************************************************************/ /***** Part III *****/ /***** Image 2 waterfall plot (multi panel) *****/ /***** *****/ /******************************************************************************/ ods listing gpath="&path\" ; ods graphics /reset outputfmt=png border=off imagename="&image2"; title font="Arial" height=12pt COLOR=Black j=c "Waterfall Plot" ; title2 font="Arial" height=8pt COLOR=GRAY j=c "(The Graph Features Can Be Customized If Needed)"; proc sgpanel data= waterfall_plot; format Start Descending_by_Change.; /*format the order of change% with Patient ID*/ panelby Tx_Group / UNISCALE= row novarname spacing=10 ; styleattrs datacolors=(lightgray lightgreen lightorange lightred) datacontrastcolors=(lightgray lightgreen lightorange lightred) ; refline 0.2 / axis=y lineattrs=(pattern=shortdash) label="PD: (*ESC*){unicode '2265'x} +20%" LABELPOS= max LABELATTRS=(family="Arial" size=8pt weight=NORMAL) ; refline -0.3 / axis=y lineattrs=(pattern=shortdash) label="PR: (*ESC*){unicode '2264'x} -30%" LABELPOS= min LABELATTRS=(family="Arial" size=8pt weight=NORMAL) ; vbar Start / response=Tumor_Size_Change group=Response baseline=0 transparency=0.2 /*transparency is important for showing the overlaided line*/; colaxis label="Patient ID" LABELATTRS=(family="Arial" size=10pt weight=bold) VALUEATTRS=(family="Arial" size=10pt weight=NORMAL) ; rowaxis label="RECIST: Tumor Size Change from Baseline (%)" values=(-1 to 1 by 0.2) VALUEATTRS=(family="Arial" size=10pt weight=NORMAL) LABELATTRS=(family="Arial" size=10pt weight=bold) ; keylegend /noBORDER title='' position= RIGHT VALUEATTRS=(family="Arial" size=8pt weight=NORMAL) ; run; title; quit; ods graphics off;