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;