The examples and information up to this point have illustrated how you can make simple changes to the survival plot. It is unlikely that you will ever have to do more than that. If you need to make changes to the overall layout of the graph, then you must modify one of the other macros. The %CompileSurvivalTemplates macro, which is the macro that compiles all the pieces that you modified, is as follows:
%macro CompileSurvivalTemplates;
%local outside;
proc template;
%do outside = 0 %to 1;
define statgraph
Stat.Lifetest.Graphics.ProductLimitSurvival%scan(2,2-&outside);
dynamic NStrata xName plotAtRisk
%if %nrbquote(&censored) ne %then plotCensored;
plotCL plotHW plotEP labelCL labelHW labelEP maxTime xtickVals
xtickValFitPol rowWeights method StratumID classAtRisk
plotTest GroupName Transparency SecondTitle TestName pValue
_byline_ _bytitle_ _byfootnote_;
BeginGraph %if %nrbquote(&graphopts) ne %then / &graphopts;;
if (NSTRATA=1)
%if &ntitles %then %do;
if (EXISTS(STRATUMID)) entrytitle &titletext1;
else entrytitle &titletext0;
endif;
%end;
%if &ntitles gt 1 %then %do;
%if not &outside %then if (PLOTATRISK=1);
entrytitle "With Number of Subjects at Risk" /
textattrs=GRAPHVALUETEXT;
%if not &outside %then %do; endif; %end;
%end;
%StmtsBeginGraph
%AtRiskLatticeStart
layout overlay / xaxisopts=(&xoptions) yaxisopts=(&yoptions);
%StmtsTop
%SingleStratum
%StmtsBottom
endlayout;
%AtRiskLatticeEnd
else
%if &ntitles %then %do; entrytitle &titletext2; %end;
%if &ntitles gt 1 %then %do;
if (EXISTS(SECONDTITLE))
entrytitle SECONDTITLE / textattrs=GRAPHVALUETEXT;
endif;
%end;
%StmtsBeginGraph
%AtRiskLatticeStart
layout overlay / xaxisopts=(&xoptions) yaxisopts=(&yoptions);
%StmtsTop
%MultipleStrata
%StmtsBottom
endlayout;
%AtRiskLatticeEnd(class)
endif;
if (_BYTITLE_) entrytitle _BYLINE_ / textattrs=GRAPHVALUETEXT;
else if (_BYFOOTNOTE_) entryfootnote halign=left _BYLINE_; endif;
endif;
EndGraph;
end;
%end;
run;
%mend;
The macro %DO loop compiles the following two templates:
Stat.Lifetest.Graphics.ProductLimitSurvival when the macro variable Outside is 0 and %SCAN(2,2-&OUTSIDE) is null
Stat.Lifetest.Graphics.ProductLimitSurvival2 when the macro variable Outside is 1 and %SCAN(2,2-&OUTSIDE) is 2
The primary difference between these templates is that when the macro variable Outside is 1, a LAYOUT LATTICE statement block is used to place the at-risk table outside the graph. When Outside is 1, the macros %AtRiskLatticeStart and %AtRiskLatticeEnd provide the LAYOUT LATTICE statement block (two cells, plot above
and at-risk table below) and the LAYOUT OVERLAY statement block for the at-risk table. The %AtRiskLatticeStart and %AtRiskLatticeEnd
macros are defined as follows:
%macro AtRiskLatticeStart;
%if &outside %then %do;
layout lattice / rows=2 rowweights=ROWWEIGHTS
columndatarange=union rowgutter=10;
cell;
%end;
%mend;
%macro AtRiskLatticeEnd(useclassopts);
%if &outside %then %do;
endcell;
cell;
layout overlay / walldisplay=none xaxisopts=(display=none);
axistable x=TATRISK value=ATRISK / &atriskopts
%if &useclassopts ne %then &classopts;;
endlayout;
endcell;
endlayout;
%end;
%mend;
The %CompileSurvivalTemplates macro relies on two other macros: %SingleStratum for the single-stratum case and %MultipleStrata for the multiple-strata case. The %SingleStratum macro is as follows:
%macro SingleStratum;
if (PLOTHW=1 AND PLOTEP=0)
bandplot LimitUpper=HW_UCL LimitLower=HW_LCL x=TIME /
displayTail=false modelname="Survival" fillattrs=GRAPHCONFIDENCE
name="HW" legendlabel=LABELHW;
endif;
if (PLOTHW=0 AND PLOTEP=1)
bandplot LimitUpper=EP_UCL LimitLower=EP_LCL x=TIME /
displayTail=false modelname="Survival" fillattrs=GRAPHCONFIDENCE
name="EP" legendlabel=LABELEP;
endif;
if (PLOTHW=1 AND PLOTEP=1)
bandplot LimitUpper=HW_UCL LimitLower=HW_LCL x=TIME /
displayTail=false modelname="Survival" fillattrs=GRAPHDATA1
datatransparency=.55 name="HW" legendlabel=LABELHW;
bandplot LimitUpper=EP_UCL LimitLower=EP_LCL x=TIME /
displayTail=false 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 /
displayTail=false modelname="Survival" display=(outline)
outlineattrs=GRAPHPREDICTIONLIMITS name="CL" legendlabel=LABELCL;
else
bandplot LimitUpper=SDF_UCL LimitLower=SDF_LCL x=TIME /
displayTail=false modelname="Survival"
fillattrs=GRAPHCONFIDENCE
name="CL" legendlabel=LABELCL;
endif;
endif;
stepplot y=SURVIVAL x=TIME / name="Survival" &tips legendlabel="Survival"
&stepopts;
if (PLOTCENSORED=1)
scatterplot y=CENSORED x=TIME / &censored &tiplabel
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 not &outside %then %do;
if (PLOTATRISK=1)
innermargin / align=bottom;
axistable x=TATRISK value=ATRISK / &atriskopts;
endinnermargin;
endif;
%end;
%mend;
The %MultipleStrata macro is as follows:
%macro MultipleStrata;
if (PLOTHW=1)
bandplot LimitUpper=HW_UCL LimitLower=HW_LCL x=TIME / &bandopts
datatransparency=Transparency;
endif;
if (PLOTEP=1)
bandplot LimitUpper=EP_UCL LimitLower=EP_LCL x=TIME / &bandopts
datatransparency=Transparency;
endif;
if (PLOTCL=1)
if (PLOTHW=1 OR PLOTEP=1)
bandplot LimitUpper=SDF_UCL LimitLower=SDF_LCL x=TIME / &bandopts
display=(outline) outlineattrs=(pattern=ShortDash);
else
bandplot LimitUpper=SDF_UCL LimitLower=SDF_LCL x=TIME / &bandopts
datatransparency=Transparency;
endif;
endif;
stepplot y=SURVIVAL x=TIME / &groups name="Survival" &tips &stepopts;
if (PLOTCENSORED=1)
scatterplot y=CENSORED x=TIME / &groups &tiplabel &censored;
endif;
%if not &outside %then %do;
if (PLOTATRISK=1)
innermargin / align=bottom;
axistable x=TATRISK value=ATRISK / &atriskopts &classopts;
endinnermargin;
endif;
%end;
%if %nrbquote(&legendopts) ne %then %do;
DiscreteLegend "Survival" / &legendopts;
%end;
%if %nrbquote(&insetopts) ne %then %do;
if (PLOTCENSORED=1)
if (PLOTTEST=1)
layout gridded / rows=2 &insetopts;
entry &censorstr;
%pValue
endlayout;
else
layout gridded / rows=1 &insetopts;
entry &censorstr;
endlayout;
endif;
else
if (PLOTTEST=1)
layout gridded / rows=1 &insetopts;
%pValue
endlayout;
endif;
endif;
%end;
%mend;