Clinical Graphs using SAS® 9.3 Sanjay Matange, SAS Institute Inc. SAS Global Forum 2015 In their 2008 paper “Graphical Approaches to the Analysis of Safety Data from Clinical Trials”, Ohad Amit, et al. have provided valuable insight into and recommendations for the analysis of safety data. The authors see several opportunities to enhance the evaluation of safety through use of graphical display of data including Dot Plots, Box Plots, Lattice and Matrix Displays. Graphical display of data provides insights into trends and correlations that are just not visible in the tabular data. Often, combining the data and summary statistics on a single display helps improve the analysis and interpretation of the results. In this handout, we show how you can use the SAS 9.3 SG Procedures and GTL to create clinical graphs by using features such as cluster groups, grouped box plots on discrete and interval axis and attribute maps. Annotation is supported with the SG Procedures, making it easier to create these graphs. A GTL program may be required to create some of the multi-cell graphs. The data for the graphs shown here is simulated. Some graphs included in this handout have been contributed by Susan Schwartz and Melisa Turner. The examples shown here include display of Lab Result over Time, Distribution of lab values by Test and Treatment, Lattice and Matrix displays of LFT tests, Patient Profiles, Adverse Event Plots sorted by relative risk and Hazard Function Plots. The code shown below each graph is reduced to fit the available space. The intention is to show the structure and key statements. The complete programs for these graphs are available at http://support.sas.com/rnd/datavisualization/yourGraphs/analyticalCustom/clinical. title 'LFT Safety Panel, Baseline vs. Study'; footnote2 j=l italic height=8pt "* For ALAT, ASAT …”; footnote3 j=l italic height=8pt " For Bilirubin Total, …”; proc sgpanel data=labs; panelby labtest visitnum / layout=lattice onepanel novarname; scatter x=pre y=result/ group=drug markerattrs=(size=9); refline 1 1.5 2 / axis=Y lineattrs=(pattern=dash); refline 1 1.5 2 / axis=X lineattrs=(pattern=dash); rowaxis integer min=0 max=4 label='Study (/ULN)' ; colaxis integer min=0 max=4 label='Baseline (/ULN) *'; keylegend/title=" " noborder; run; begingraph / <options>; entrytitle "Lab Values by Study Week"; layout gridded / rowgutter=5; layout datapanel classvars=(treatment) / <options>; layout prototype / cycleattrs=true; seriesplot X=visit Y=sgot / <options>; seriesplot X=visit Y=aph / yaxis=Y2 <options>; endlayout; endlayout; discretelegend "series1" "series2" / <options> ; endlayout; endgraph; begingraph / <options>; entrytitle 'Distribution of Maximum Liver Function Test …’; layout overlay / < yaxisopts > <y2axisopts> <xaxisopts>; boxplot x=Test y=A / discreteoffset=-0.2 boxwidth=.2 name='a' legendlabel='Drug A (N=209)' <options>; boxplot x=Test y=B / discreteoffset=0.2 boxwidth=.2 name='b' legendlabel='Drug B (N=405)' yaxis=y2 <options>; referenceline y=1 / lineattrs=(pattern=dot); dropline x='BILTOT' y=1.5 / dropto=Y yaxis=y2 discreteoffset=-.4 <options>; dropline x='ALKPH' y=2.0 / dropto=Y yaxis=y discreteoffset=.4 <options>; discretelegend 'a' 'b' / location=inside <options>; endlayout; endgraph; begingraph / <options>; entrytitle 'Hazard Function for Adverse Events …'; layout overlay / yaxisopts=(label='Hazard Rate') <options>; stepplot x=day y=A / errorupper=AHigh errorlower=ALow justify=center name='a' <options>; stepplot x=day y=B / errorupper=BHigh errorlower=BLow justify=center name='b' < options>; discretelegend 'a' 'b' / location=inside across=1 <options>; innermargin; blockplot x=day block=BRisk / <options>; blockplot x=day block=ARisk / <options>; endinnermargin; endlayout; entryfootnote halign=left 'Table: Average number of …”; endgraph; title 'Median of Lipid Profile by Visit and Treatment'; proc sgplot data=lipid_grp; scatter x=day y=median / yerrorlower=lcl yerrorupper=ucl group=trt groupdisplay=cluster clusterwidth=0.5 markerattrs=(symbol=circlefilled); series x=day y=median / group=trt groupdisplay=cluster clusterwidth=0.5 lineattrs=(thickness=2) name='s'; yaxis label='Median with 95% CL' grid; xaxis display=(nolabel); keylegend 's' / title='Treatment' location=inside position=topright across=1; run; title "Adverse Events for Patient Id = xx-xxx-xxxx"; proc sgplot data=ae2 nocycleattrs dattrmap=attrmap; highlow y=aeseq low=stday high=enday / group=aesev lowlabel=aedecod type=bar barwidth=0.8 lineattrs=(color=black) lowcap=lcap highcap=hcap attrid=Severity name='sev'; scatter x=aestdate y=aeseq / markerattrs=(size=0) x2axis; refline 0 / axis=x lineattrs=(thickness=1 color=black); yaxis display=(nolabel noticks novalues) type=discrete; xaxis grid label='Study' values=(&minda to &maxday by 2); x2axis notimesplit values=(&mindate to &maxdate); keylegend 'sev'/ title='Severity :'; run; begingraph; entrytitle 'Distribution of ASAT by Time and Treatment'; layout lattice / columns=1 COLUMNDATARANGE=UNION columndatarange=union rowweights=(0.07 0.86 0.07); columnaxes; columnaxis / display=(tickvalues) linearopts=(tickvaluelist=(0 1 2 4 8 12 24 26)); endcolumnaxes; layout overlay / yaxisopts=(display=(tickvalues)); scatterplot x=week y=over2label / group=Drug markercharacter=over2 ; referenceline x=25 / lineattrs=(pattern=solid); endlayout; layout overlay / xaxisopts = (display=(tickvalues label)); boxplot x=week y=value / group=drug name="d" whiskerattrs=(thickness=2) groupdisplay=cluster display=(mean median outliers) outlineattrs=(thickness=2); referenceline x=25 / lineattrs=(pattern=solid); referenceline y=1.0 / lineattrs=(pattern=shortdash); referenceline y=2.0 / lineattrs=(pattern=dash); referenceline y=0 / lineattrs=(pattern=dash); endlayout; layout overlay / xaxisopts=(display=none) yaxisopts=(display=(tickvalues)); scatterplot x=week y=drug / group=Drug clusterwidth=0.5 markercharacter=atrisk; referenceline x=25 / lineattrs=(pattern=solid); endlayout; sidebar / align=bottom spacefill=false; discretelegend "Drug A" "Drug B"; endsidebar; endLayout; endgraph; end; run; begingraph / <options>; entrytitle 'Matrix Display of Maximum LFT Values'; layout lattice / columns=3 columndatarange=union rowdatarange=union order=rowmajor <options>; sidebar; layout overlay; discretelegend 's' / across=2 border=false; endlayout; endsidebar; /* Column Axes Block */ /* Row Axes Block */ layout overlay / yaxisopts=(linearopts=(thresholdmax=1)); scatterplot x=asat y=alat / group=drug name='s' <options>; /* Reference lines */ endlayout; /* Empty Cell */ /* Empty Cell */ layout overlay / yaxisopts=(linearopts=(thresholdmax=1)); scatterplot x=asat y=biltot / group=drug <options>; /* Reference lines */ endlayout; layout overlay / yaxisopts=(linearopts=(thresholdmax=1)); scatterplot x=alat y=biltot / group=drug <options>; /* Reference lines */ endlayout; /* Empty Cell */ layout overlay / yaxisopts=(linearopts=(thresholdmax=1)); scatterplot x=asat y=alkph / group=drug <options>; /* Reference lines */ endlayout; layout overlay / yaxisopts=(linearopts=(thresholdmax=1)); scatterplot x=alat y=alkph / group=drug <options>; /* Reference lines */ endlayout; layout overlay / yaxisopts=(linearopts=(thresholdmax=1)); scatterplot x=biltot y=alkph / group=drug <options>; /* Reference lines */ endlayout; endlayout; entryfootnote halign=left "For ALAT, ASAT …”; entryfootnote halign=left "For BILTOT, the …"; endgraph; begingraph / <options>; entrytitle 'Immunology Profile by Treatment'; layout gridded; layout datalattice columnvar=trt rowvar=lbparm / <options>; layout prototype; blockplot x=xval block=cyc / <options>; seriesplot x=xval y=sival / group=pt name='a' <options>; endlayout; endlayout; discretelegend 'a' / title ='Patient' across=8; endlayout; endgraph; title 'Depression After Treatment by Visit and Treatment'; proc sgpanel data=depression; panelby phase / layout=columnlattice onepanel novarname uniscale=row spacing=2; vbox score / category=visit group=trt clusterwidth=0.75 boxwidth=0.9 transparency=0.3 lineattrs=(color=black) whiskerattrs=(color=black); colaxis display=(nolabel); rowaxis grid; run; proc sgplot data=eyeIrritation; vbarparm category=time response=percent / group=chartvar limitupper=ucl limitlower=lcl dataskin=gloss transparency=0.3 barwidth=0.9 limitattrs=graphdatadefault; scatter x=time y=yn / group=chartvar groupdisplay=cluster y2axis markerchar=n markercharattrs=graphdatadefault; yaxis offsetmin=0.05 grid max=100; y2axis offsetmax=0.97 display=none; xaxis display=(nolabel); run; title 'Top Twenty Adverse Events Sorted by Frequency'; proc sgplot data=aerev; refline refline / lineattrs=graphdata1(thickness=16) transparency=0.8; scatter y=aedecod x=percent / group=arm name='scatter'; keylegend / location=inside position=bottomright across=1; xaxis display=(nolabel) ; yaxis display=(nolabel) offsetmin=0.03 offsetmax=0.03; run; For more examples, tips and tricks on creating graphs using SG Procedures and GTL, visit our blog at http://blogs.sas.com/content/graphicallyspeaking/.
© Copyright 2026 Paperzz