Hello, I have this graph below which I created in SAS 9.2 M2 using the Kaplan Meier Template - Stat.Lifetest.Graphics.ProductLimitSurvival. I would simply like to add another two curves to the plot (which are not related to Kaplan Meier). I would like to achieve the creation of the plot just by using the dataset that goes into proc lifetest and modifying the Stat.Lifetest.Graphics.ProductLimitSurvival, i.e. I want to avoid outputting a dataset from Proc Lifetest and then subsequently creating a dataset that has got all the statistics that I want to plot, and then using GTL and SGRENDER to make the plot. Is that possible please? One reason why I would like to avoid using GTL and SGRender is because I think that the confidence bands will be difficult to obtain and plot. Also it would be simpler to just use the dataset that goes into SGPLOT. It would be interesting to know which dataset goes into using this template. I think Warren Kuhfeld desribes it as a Data object in his paper - https://support.sas.com/resources/papers/proceedings13/427-2013.pdf. Here is the code I used to create the above plot. **** graphic options for KM plots - Changing LY colour to Red ***;
options mprint;
%macro ProductLimitStat(n=,fmt=F6.1);
dynamic PctMedianConfid;
%if &n=1 %then %do;
dynamic NObs NEvent Median LowerMedian UpperMedian;
%end;
%else %do;
%do i=1 %to &n;
dynamic StrVal&i NObs&i NEvent&i Median&i LowerMedian&i UpperMedian&i;;
%end;
%end;
%if &n=1 %then %let ncol=4;
%else %let ncol=5;
layout overlay / pad=(top=5);
layout gridded / columns=&ncol border=TRUE;
%if &n>1 %then entry " ";;
entry "No. of Patients";
entry "Event";
entry "Censored";
entry "Median Survival (" PctMedianConfid " CI)";
%do i=1 %to &n;
%if &n=1 %then %do;
entry NObs;
entry NEvent;
entry eval(NObs-NEvent);
entry eval(put(Median,&fmt)) " ( "
eval(put(LowerMedian,&fmt)) " "
eval(put(UpperMedian,&fmt)) " )";
%end;
%else %do;
entry halign=left StrVal&i;
entry NObs&i;
entry NEvent&i;
entry eval(NObs&i-NEvent&i);
entry eval(put(Median&i,&fmt)) " ( "
eval(put(LowerMedian&i,&fmt)) " "
eval(put(UpperMedian&i,&fmt)) " )";
%end;
%end;
endlayout;
endlayout;
%mend ProductLimitStat;
proc template;
source Stat.Lifetest.Graphics.ProductLimitSurvival;
define statgraph Stat.Lifetest.Graphics.ProductLimitSurvival;
dynamic NStrata xName plotAtRisk plotCensored plotCL plotHW plotEP labelCL labelHW labelEP
maxTime method StratumID classAtRisk plotBand plotTest GroupName yMin Transparency
SecondTitle TestName pValue;
mvar legtit; * Using this instead of GROUPNAME to add the title;
BeginGraph;
if (NSTRATA=1)
if (EXISTS(STRATUMID))
entrytitle "";
else
entrytitle "";
endif;
if (PLOTATRISK)
entrytitle "" / textattrs=GRAPHVALUETEXT;
endif;
layout lattice / rows=1 columns=1;
layout overlay / xaxisopts=(shortlabel=XNAME offsetmin=.05 linearopts=(viewmax=MAXTIME))
yaxisopts=(label="Survival Probability" shortlabel="Survival" linearopts=(viewmin=0
viewmax=1 tickvaluelist=(0 .2 .4 .6 .8 1.0)));
if (PLOTHW=1 AND PLOTEP=0)
bandplot LimitUpper=HW_UCL LimitLower=HW_LCL x=TIME / modelname="Survival" fillattrs
=GRAPHCONFIDENCE name="HW" legendlabel=LABELHW;
endif;
if (PLOTHW=0 AND PLOTEP=1)
bandplot LimitUpper=EP_UCL LimitLower=EP_LCL x=TIME / modelname="Survival" fillattrs
=GRAPHCONFIDENCE name="EP" legendlabel=LABELEP;
endif;
if (PLOTHW=1 AND PLOTEP=1)
bandplot LimitUpper=HW_UCL LimitLower=HW_LCL x=TIME / modelname="Survival" fillattrs
=GRAPHDATA1 datatransparency=.55 name="HW" legendlabel=LABELHW;
bandplot LimitUpper=EP_UCL LimitLower=EP_LCL x=TIME / modelname="Survival" fillattrs=
GRAPHDATA2 datatransparency=.55 name="EP" legendlabel=LABELEP;
endif;
if (PLOTCL=1)
if (PLOTHW=1 OR PLOTEP=1)
bandplot LimitUpper=SDF_UCL LimitLower=SDF_LCL x=TIME / modelname="Survival" display
=(outline) outlineattrs=GRAPHPREDICTIONLIMITS name="CL" legendlabel=LABELCL;
else
bandplot LimitUpper=SDF_UCL LimitLower=SDF_LCL x=TIME / modelname="Survival"
fillattrs=GRAPHCONFIDENCE name="CL" legendlabel=LABELCL;
endif;
endif;
stepplot y=SURVIVAL x=TIME / name="Survival" rolename=(_tip1=ATRISK _tip2=EVENT) tip=(y
x Time _tip1 _tip2) legendlabel="Survival";
if (PLOTCENSORED=1)
scatterplot y=CENSORED x=TIME / markerattrs=(symbol=plus) name="Censored"
legendlabel="Censored";
endif;
if (PLOTCL=1 OR PLOTHW=1 OR PLOTEP=1)
discretelegend "Censored" "CL" "HW" "EP" / location=outside halign=center;
else
if (PLOTCENSORED=1)
discretelegend "Censored" / location=inside autoalign=(topright bottomleft);
endif;
endif;
if (PLOTATRISK=1)
innermargin / align=bottom;
blockplot x=TATRISK block=ATRISK / repeatedvalues=true display=(values) valuehalign=
start valuefitpolicy=truncate labelposition=left labelattrs=GRAPHVALUETEXT
valueattrs=GRAPHDATATEXT (size=7pt) includemissingclass=false;
endinnermargin;
endif;
endlayout;
columnheaders;
%ProductLimitStat(n=1);
endcolumnheaders;
endlayout;
else
entrytitle "";
if (EXISTS(SECONDTITLE))
entrytitle "" / textattrs=GRAPHVALUETEXT;
endif;
layout lattice / rows=1 columns=1;
layout overlay / xaxisopts=(shortlabel=XNAME offsetmin=.05 linearopts=(viewmax=MAXTIME))
yaxisopts=(label="Survival Probability" shortlabel="Survival" linearopts=(viewmin=0
viewmax=1 tickvaluelist=(0 .2 .4 .6 .8 1.0)));
if (PLOTHW)
bandplot LimitUpper=HW_UCL LimitLower=HW_LCL x=TIME / group=STRATUM index=STRATUMNUM
modelname="Survival" datatransparency=Transparency;
endif;
if (PLOTEP)
bandplot LimitUpper=EP_UCL LimitLower=EP_LCL x=TIME / group=STRATUM index=STRATUMNUM
modelname="Survival" datatransparency=Transparency;
endif;
if (PLOTCL)
if (PLOTBAND)
bandplot LimitUpper=SDF_UCL LimitLower=SDF_LCL x=TIME / group=STRATUM index=
STRATUMNUM modelname="Survival" display=(outline);
else
bandplot LimitUpper=SDF_UCL LimitLower=SDF_LCL x=TIME / group=STRATUM index=
STRATUMNUM modelname="Survival" datatransparency=Transparency;
endif;
endif;
stepplot y=SURVIVAL x=TIME / group=STRATUM index=STRATUMNUM name="Survival" rolename=(
_tip1=ATRISK _tip2=EVENT) tip=(y x Time _tip1 _tip2);
if (PLOTCENSORED)
scatterplot y=CENSORED x=TIME / group=STRATUM index=STRATUMNUM markerattrs=(symbol=
plus);
endif;
if (PLOTATRISK)
innermargin / align=bottom;
blockplot x=TATRISK block=ATRISK / class=CLASSATRISK repeatedvalues=true display=(
label values) valuehalign=start valuefitpolicy=truncate labelposition=left
labelattrs=GRAPHVALUETEXT valueattrs=GRAPHDATATEXT (size=7pt) includemissingclass
=false;
endinnermargin;
endif;
DiscreteLegend "Survival" / title=/*GROUPNAME*/ legtit location=outside;
if (PLOTCENSORED)
if (PLOTTEST)
layout gridded / rows=2 autoalign=(TOPRIGHT BOTTOMLEFT TOP BOTTOM) border=true
BackgroundColor=GraphWalls:Color Opaque=true;
entry "+ Censored";
if (PVALUE < .0001)
/* Removing log rank */
/*entry TESTNAME " p " eval (PUT(PVALUE, PVALUE6.4))*/
entry "";
else
/*entry TESTNAME " p=" eval (PUT(PVALUE, PVALUE6.4))*/
entry "";
endif;
endlayout;
else
layout gridded / rows=1 autoalign=(TOPRIGHT BOTTOMLEFT TOP BOTTOM) border=true
BackgroundColor=GraphWalls:Color Opaque=true;
entry "+ Censored";
endlayout;
endif;
else
if (PLOTTEST)
layout gridded / rows=1 autoalign=(TOPRIGHT BOTTOMLEFT TOP BOTTOM) border=true
BackgroundColor=GraphWalls:Color Opaque=true;
if (PVALUE < .0001)
entry TESTNAME " p " eval (PUT(PVALUE, PVALUE6.4));
else
entry TESTNAME " p=" eval (PUT(PVALUE, PVALUE6.4));
endif;
endlayout;
endif;
endif;
endlayout;
columnheaders;
if (NStrata=2) %ProductLimitStat(n=2);endif;
if (NStrata=3) %ProductLimitStat(n=3);endif;
if (NStrata=4) %ProductLimitStat(n=4);endif;
if (NStrata=5) %ProductLimitStat(n=5);endif;
if (NStrata=6) %ProductLimitStat(n=6);endif;
endcolumnheaders;
endlayout;
endif;
EndGraph;
end;
run;
goptions reset = all;
ods graphics / reset = all;
*********************;
*Add this code before the lifetest.;
*********************;
*Add this code before the lifetest.;
data bmt;
set sashelp.BMT;
xval = 250;
yval = 0.2;
run;
goptions reset = all;
ods graphics / reset = all imagename= "kaplan";
ods listing gpath = "C:\Users\Desktop\Helpful plots\kaplan_meier_with_new_data";
ods trace on;
proc lifetest data=bmt plots=survival(cb=hw atrisk=0 to 2500 by 500);
time T * Status(0);
strata Group / test=logrank adjust=sidak;
run;
ods trace off;
ods graphics off; Many thanks in advance, Kriss Harris
... View more