Kaplan-Meier Survival Plotting Macro %NEWSURV Jeffrey Meyers Mayo Clinic, Rochester, Minnesota 1 BB-13
#pharmasug Contents Macro Overview What the macro does How the macro does it – Computed Statistics – Designing the Plot – Designing the Lattice Statistical Report Table Conclusion 2
#pharmasug Macro Overview (Plot) 3
#pharmasug Macro Overview (Statistical Report) 4 General Statistical Report Table Example Event/Total Median (95% CI) † Hazard Ratio (95% CI) ‡ Survival Estimates (95% CI) † P-value SASHELP.BMT Data set with no Class Variable All Patients83/ ( )1 Years: 58.3 ( ) 2 Years: 42.0 ( ) This is the footnote for this model SASHELP.BMT Data set with Class Variable Group $ ALL24/381.1 (0.5-NE)Ref1 Years: 54.9 ( ) 2 Years: 35.3 ( ) AML-High Risk34/450.5 ( )1.47 ( )1 Years: 37.8 ( ) 2 Years: 24.4 ( ) AML-Low Risk25/546.0 (1.9-NE)0.56 ( )1 Years: 77.8 ( ) 2 Years: 61.1 ( ) This is the footnote for this model † Kaplan-Meier method; ‡ Cox model; $ Score test; This also allows an overall footnote
#pharmasug Sample Dataset SASHELP.BMT – SAS 9.3 GROUP – categorical – Acute Lymphoblastic Leukemia (ALL) – Acute Myeloid Leukemia (AML) High Risk and Low Risk T – time from transplant STATUS – survival status – 0=Alive – 1=Dead 5
#pharmasug Only Required Variables DATA, TIME, CENS, CEN_VL Dataset Transformations LANDMARK CLASS & WHERE XDIVISOR 6 Line and Axes Transformations COLOR & PATTERN XMIN, XMAX, &XINCREMENT YTYPE, YMIN, YMAX & YINCREMENT Plot Summary Table Options CLASSORDER CLASSVALALIGN TIMELIST & TIMEDX CLASSREF PLOTPVAL DISPLAY Key Features/Parameters %NEWSURV(…, CLASSORDERMETHOD=list, CLASSORDER=3 1 2, CLASSREF=AML-Low Risk, CLASSVALALIGN=left, DISPLAY=legend total event hr pval timelist, PLOTPVAL=logrank, TIMELIST=0.5 1, TIMEDX=Years); %NEWSURV(…, CLASS=group, WHERE=group in('ALL' 'AML-High Risk'), XDIVISOR=30.44, LANDMARK=3.0); %NEWSURV( DATA=sashelp.bmt, TIME=T, CENS=status, CEN_VL=0); %NEWSURV(…, PATTERN=2 3 4, COLOR=blue red green, LINESIZE=3pt, SYMBOLSIZE=10pt, YTYPE=ppt, YMIN=0.25,YMAX=1,YINCREMENT=0.05, XMIN=0,XMAX=7.5,XINCREMENT=0.5, YLABEL=Proportion Alive, XLABEL=Disease-Free Survival Time (Years));
#pharmasug Patients-at-Risk Table Variations 7 %newsurv(…, RISKLABELLOCATION=left, RISKLOCATION=bottom, RISKLIST=0 to 7.5 by 0.5, RISKCOLOR=1, PARHEADER=Patients-at-Risk); RISKLABELLOCATION PARHEADER RISKLOCATION RISKCOLOR
#pharmasug Lattice of Plots 8 %NEWSURV(TIME=T|T, CENS=status,CEN_VL=0, SREVERSE=1|0, ROWS=1,COLUMNS=2, ORDER=rowmajor, TITLE=%str(A%))|%str(B%)), FOOTNOTE=Footnote1|Footnote2, OVTITLE=Title for entire image, OVFOOTNOTE=Footnote for entire image,…); OVTITLE TITLE FOOTNOTE OVFOOTNOTE SREVERSE
#pharmasug Output Methods RTF, PDF, HTML, Listing Various file types (PNG, JPEG, TIFF, EMF, …) DPI settings Scalable vector graphics (9.3 and later) From macro vs. within ODS tags 9
#pharmasug Error Checking Macro checks most parameter input Custom error messages: ERROR: (Model 1: DISPLAY): TOTL is not in the list of valid values ERROR: (Model 1: DISPLAY): Possible values are LEGEND|HR|MEDIAN|TOTAL|EVENT|TIMELIST| PVAL|TABLECOMMENTS ERROR: 1 pre-run errors listed ERROR: Macro NEWSURV will cease 10
#pharmasug Computed Statistics 2 LIFETEST procedures, 1 PHREG procedure N patients, N events Median time-to-event Kaplan-Meier event-free rate Cox proportional hazards ratio P-value Patients-at-risk numbers 11
#pharmasug LIFETEST #1 – OUTSURV Option 12 PROC LIFETEST DATA=sashelp.bmt OUTSURV=os1; STRATA group; TIME t*status(0); RUN;
#pharmasug LIFETEST #1 – ODS Output SURVIVALPLOT 13 ODS GRAPHICS ON; PROC LIFETEST DATA=sashelp.bmt PLOT(SURVIVAL(ATRISK=1000,2000)); STRATA group; TIME t*status(0); ODS OUTPUT SURVIVALPLOT=splot (KEEP=time tatrisk stratumnum atrisk WHERE=(tatrisk ^=.)); RUN;
#pharmasug LIFETEST #2 – OUTSURV Option w/REDUCEOUT OPTION 14 PROC LIFETEST DATA=sashelp.bmt OUTSURV=os2 REDUCEOUT TIMELIST= ; STRATA group; TIME t*status(0); RUN;
#pharmasug LIFETEST #2 – ODS Output CENSOREDSUMMARY 15 PROC LIFETEST DATA=sashelp.bmt; STRATA group; TIME t*status(0); ODS OUTPUT CENSOREDSUMMARY=summary; RUN;
#pharmasug LIFETEST #2 – ODS Output QUARTILES 16 PROC LIFETEST DATA=sashelp.bmt; STRATA group; TIME t*status(0); ODS OUTPUT QUARTILES=quartiles; RUN;
#pharmasug LIFETEST #2 – ODS Output HOMTESTS 17 PROC LIFETEST DATA=sashelp.bmt; STRATA group / logrank wilcoxon; TIME t*status(0); ODS OUTPUT HOMTESTS=pval1; RUN;
#pharmasug PHREG – ODS Output PARAMETERESTIMATES 18 PROC PHREG DATA=sashelp.bmt; CLASS group; MODEL t*status(0) = group / RISKLIMITS; ODS OUTPUT PARAMETERESTIMATES=hazards (keep=classval0 hazardratio hrlowercl hruppercl); RUN;
#pharmasug PHREG – ODS Output TYPE3 19 PROC PHREG DATA=sashelp.bmt; CLASS group; MODEL t*status(0) = group / TYPE3(score lr); ODS OUTPUT TYPE3=pval2 (keep=effect problrchisq probscorechisq); RUN;
#pharmasug Statistics Saved as Macro Variables SUMMARY OS2 QUARTILES HAZARDS PVAL1 PVAL2 N patients/events Event-free rates Median time-to-event Hazard ratios Logrank/Wilcoxon Score/Likelihood-ratio 20 SQL Procedure
#pharmasug Only variables used in plot statements —Step plots —Censor scatterplots —Patients-at-risk scatterplots Plot Data Set 21
#pharmasug Plot Data Set – Step Plot and Censor Scatterplot Columns Variables – Cl#_#: CLASS level – T#_#: time – C#_#: Survival function estimate when censor – S#_#: Survival function estimate #_#: – First #: CLASS level number – Second #: model number 22
#pharmasug Plot Data Set – Step Plot and Censor Scatterplot Columns 23
#pharmasug Multiple Plots in One Window 24 STEPPLOT X=t Y=survival / GROUP=group NAME=‘stepplot’ LINEATTRS=(THICKNESS=4pt); DISCRETELEGEND ‘stepplot’ / …; STEPPLOT X=t1 Y=survival1 / LEGENDLABEL=“ALL” NAME=‘stepplot1’ LINEATTRS=(THICKNESS=4pt COLOR=blue PATTERN=1); STEPPLOT X=t1 Y=survival1 /…; STEPPLOT X=t2 Y=survival2 / LEGENDLABEL=“AML-High Risk” NAME=‘stepplot2’ LINEATTRS=(THICKNESS=4pt COLOR=cxB2182B PATTERN=4); STEPPLOT X=t2 Y=survival2 /…; STEPPLOT X=t3 Y=survival3 / LEGENDLABEL=“AML-Low Risk” NAME=‘stepplot3’ LINEATTRS=(THICKNESS=4pt COLOR=cx01665E PATTERN=8); DISCRETELEGEND ‘stepplot1’ ‘stepplot2’ ‘stepplot3’/ …; One STEPPLOT statement Multiple STEPPLOT statement
#pharmasug DATA _plot; MERGE os1 (WHERE=(group=“ALL”) RENAME=(t=t1 survival=survival1) KEEP=t1 survival1) os1 (WHERE=(group=“AML-High Risk”) RENAME=(t=t2 survival=survival2) KEEP=t2 survival2) os1 (WHERE=(group=“AML-Low Risk”) RENAME=(t=t3 survival=survival3) KEEP=t3 survival3); RUN; Turn Data by Categorical Variable into Multiple Variables 25
#pharmasug Plot Data Set – Patients-at-risk Scatterplot Variables Variables: – Time#_#: time-point values – Atrisk#_#: Number of patients-at-risk – Y#_#: Constant value of 1 EVAL function #_#: – First #: CLASS level number – Second #: model number 26
#pharmasug MARKERCHARACTER Option SCATTERPLOT X=time1_1 Y=eval(y1_1*0+1) / … MARKERCHARACTER=ATRISK1_1; SCATTERPLOT X=time1_1 Y=eval(y1_1*0+1) / …;
#pharmasug Plot Data Set – Patients-at-risk Scatterplot Variables 28
#pharmasug Plot Data Set – Patients-at-risk Header Scatterplot Variables Variables: – parx_#: Constant value of 1 for EVAL function – pary_#: Constant value of 1 for EVAL function – partitle_#: Header text string _#: model number 29
#pharmasug Plot Layout 30 Model Title Model Footnote Plot Window Patients-at-Risk Window X-Label Y-Label Class Level 1 Class Level 2 Class Level Image taken from SAS 9.3 Graph Template Language Reference Model Title Model Footnote Plot Window X-Label Y-Label
#pharmasug Plot Layout 31 This title is placed inside of a SIDEBAR block with ALIGN=TOP This footnote is placed inside of a SIDEBAR block with ALIGN=BOTTOM Time (Years) Proportion Alive and Disease-Free Censor 6.0 (1.9-NE)2554AML-Low Risk 0.5 ( )3445AML-High Risk 1.1 (0.5-NE)2438ALL Median (95% CI)EventTotalDisease Group Time (Years) Proportion Alive and Disease-Free Censor 6.0 (1.9-NE)2554AML-Low Risk 0.5 ( )3445AML-High Risk 1.1 (0.5-NE)2438ALL Median (95% CI)EventTotalDisease Group
#pharmasug Lattice of Plots 32
#pharmasug Lattice Layout of Plots Process Flow 33 Temporary data set w/transformations Analysis procedures Create plot and output data sets Create macro variables for ENTRY statements Begin template and define number of cells Create cell axes Run plot statements REPORT procedure SGRENDER procedure Run output options Delete temporary datasets Error Checking
#pharmasug Plot Summary Table 34
#pharmasug Create text Placed inside/outside plot Anchored by combination of position terms – Left/Center/Right – Top/Center/Bottom Powerful w/LAYOUT GRIDDED ENTRY Statements Red Text Blue Text Green TextBlack Text Green Text X 2 <64 ENTRY HALIGN=center 'Red Text‘ / VALIGN=top TEXTATTRS= (COLOR=red SIZE=14pt); ENTRY HALIGN=left ‘Blue Text’ / VALIGN=bottom TEXTATTRS= (COLOR=blue SIZE=14pt); ENTRY HALIGN=left ‘Green Text’ / VALIGN=top TEXTATTRS= (COLOR=green SIZE=14pt); ENTRY HALIGN=left ‘Black Text’ / VALIGN=top TEXTATTRS= (COLOR=black SIZE=14pt); LAYOUT GRIDDED / ROWS=2 HALIGN=right VALIGN=top BORDER=true; ENTRY HALIGN=left ‘Green Text’ / VALIGN=top TEXTATTRS= (COLOR=green SIZE=14pt); ENTRY HALIGN=left ‘Black Text’ / VALIGN=top TEXTATTRS= (COLOR=black SIZE=14pt); ENDLAYOUT; ENTRY HALIGN=right "X" {sup "2"} {unicode "2264"x} "64" / VALIGN=bottom TEXTATTRS=(COLOR=black SIZE=14pt);
#pharmasug LAYOUT GRIDDED 36
#pharmasug Non-Visible Items Still Take up Space 37 White Line AML Low-Risk AML High-Risk ALL STEPPLOT X=t1 Y=survival1 / LINEATTRS=(color=white) NAME='white' LEGENDLABEL='White Line'; STEPPLOT X=t1 Y=survival1 / NAME=‘class1’ …; STEPPLOT X=t2 Y=survival2 / NAME=‘class2’ …; STEPPLOT X=t3 Y=survival3 / NAME=‘class3’ …; LAYOUT GRIDDED / COLUMNS=1 ROWS=2 …; DISCRETELEGEND ‘class1’ ‘class2’ ‘class3’ / …; DISCRETELEGEND 'white' / BACKGROUNDCOLOR=red OPAQUE=true …; ENDLAYOUT;
#pharmasug Rendering in Order Disease-Free Survival Time Survival Distribution Function Estimate ALL Black AML-Low Risk AML-High Risk ALL SCATTERPLOT X=t2 Y=survival2 / MARKERATTRS=(symbol=diamondfilled color=black) NAME='black' LEGENDLABEL='ALL Black'; SCATTERPLOT X=t Y=survival / MARKERATTRS=(symbol=diamondfilled) GROUP=group NAME='group'; DISCRETELEGEND 'black' 'group' / …;
#pharmasug ( ) LegendClass ValueTotalEventsTime-PointKM Estimate Score P - value: Censor Table Comment1 2 3 ALL AML-High Risk AML-Low Risk Years ( ) 0.35( ) 0.38( ) 0.24( ) 0.78( ) Plot Summary Table Design 39
#pharmasug Statistical Report Table 40 General Statistical Report Table Example Event/Total Median (95% CI) † Hazard Ratio (95% CI) ‡ Survival Estimates (95% CI) † P-value SASHELP.BMT Data set with no Class Variable All Patients83/ ( )1 Years: 58.3 ( ) 2 Years: 42.0 ( ) This is the footnote for this model SASHELP.BMT Data set with Class Variable Group $ ALL24/381.1 (0.5-NE)Ref1 Years: 54.9 ( ) 2 Years: 35.3 ( ) AML-High Risk34/450.5 ( )1.47 ( )1 Years: 37.8 ( ) 2 Years: 24.4 ( ) AML-Low Risk25/546.0 (1.9-NE)0.56 ( )1 Years: 77.8 ( ) 2 Years: 61.1 ( ) This is the footnote for this model † Kaplan-Meier method; ‡ Cox model; $ Score test; This also allows an overall footnote
#pharmasug Multiple Macro Calls Can be Output in the same Report 41 Event/Total Survival Estimates (95% CI) † All Patients, In Years, Survival at 1 Year, Using Proportions Disease Group ALL24/38 1 Year: 0.55 ( ) AML-High Risk34/45 1 Year: 0.38 ( ) AML-Low Risk25/54 1 Year: 0.78 ( ) This comes from the first macro call Time Landmarked at 500 Days, In Days, Subsequent Survival at 365 Days, Using Percentages Disease Group ALL3/ Days: 0.80 ( ) AML-High Risk2/ Days: 0.85 ( ) AML-Low Risk7/ Days: 0.89 ( ) This comes from the second macro call † Kaplan-Meier method; %NEWSURV(…, summary=0,out=table); %NEWSURV(…, summary=1,out=table, newtable=0);
#pharmasug 42 Name: Jeffrey Meyers Enterprise: Mayo Clinic Address: 200 1st St SW City, State ZIP: Rochester, MN Work Phone: Twitter: jmeyers_spa