Hi everyone, this forum has been great help to me in the past, so I'm hoping you can help me out of another rut. I am trying to customize the x-axis tickmarks in a proc lifetest hazard plot to be from 0 to 24. I have never used a macro or template before, but I'm hoping I'll be able to figure one out for this. Here is what I have tried so far:
The code I found on SAS.com (only changed the numbers for x and y values)
proc template;
define statgraph Stat.Lifetest.Graphics.ProductLimitSurvival;
dynamic NStrata xName plotAtRisk plotCensored plotCL plotHW plotEP
labelCL labelHW labelEP maxTime StratumID classAtRisk plotBand
plotTest GroupName yMin Transparency SecondTitle TestName pValue;
begingraph;
if (NSTRATA=1)
if (EXISTS(STRATUMID))
entrytitle "Product-Limit Survival Estimate" " for " STRATUMID;
else
entrytitle "Product-Limit Survival Estimate";
endif;
if (PLOTATRISK)
entrytitle "with Number of Subjects at Risk" / textattrs=
GRAPHVALUETEXT;
endif;
/* Original syntax */
* 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)));
/* Modified syntax - modify axes */
layout overlay /
xaxisopts=(shortlabel=XNAME offsetmin=.05
linearopts=(viewmax=24 tickvaluelist=(0 6 12 18 24)))
yaxisopts=(label="Survival Probs" shortlabel="Survival"
linearopts=(viewmin=.25 viewmax=.3 tickvaluelist=(0 0.05 0.1 0.15 0.2 0.25 0.3)));
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;
else
entrytitle "Product-Limit Survival Estimates";
if (EXISTS(SECONDTITLE))
entrytitle SECONDTITLE / textattrs=GRAPHVALUETEXT;
endif;
/* Original syntax */
* 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)));
/* Modified syntax - modify axes */
layout overlay /
xaxisopts=(shortlabel=XNAME offsetmin=.05
linearopts=(viewmax=24 tickvaluelist=(0 6 12 18 24)))
yaxisopts=(label="Survival Probs" shortlabel="Survival"
linearopts=(viewmin=0 viewmax=.3 tickvaluelist=(0 0.05 0.1 0.15 0.2 0.25 0.3)));
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 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)
entry TESTNAME " p " eval (PUT(PVALUE, PVALUE6.4));
else
entry TESTNAME " p=" eval (PUT(PVALUE, PVALUE6.4));
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;
endif;
endgraph;
end;
run;
And added my proc lifetest code:
ods html;
ods graphics on;
proc lifetest data=lvad.inf4 method=life plots=survival(cl cb=hw strata=panel)
plots=hazard(cl) intervals = (3 to 24 by 1) maxtime = 24;
time Months*inf_ind(0);
;
run;
ods graphics off ;
ods html close;
But the closest I get is this:
As you can see, the line stops at 24 but the tickmark continues to 25. Please help!!! Thanks!
There is an entire chapter devoted to modifying the KM plot with examples that do not require direct template modification.
@WarrenKuhfeld are the macros available in a location that's more user friendly to copy from? Ie how the documentation examples are stored?
I did see the data _null_ code in the documentation on how to download it automatically.
data _null_;
%let url = //support.sas.com/documentation/onlinedoc/stat/ex_code/142;
infile "http:&url/templft.html" device=url;
file 'macros.tmp';
retain pre 0;
input;
_infile_ = tranwrd(_infile_, '&', '&');
_infile_ = tranwrd(_infile_, '<' , '<');
if index(_infile_, '</pre>') then pre = 0;
if pre then put _infile_;
if index(_infile_, '<pre>') then pre = 1;
run;
%inc 'macros.tmp' / nosource;
Maybe something simpler like:
https://blogs.sas.com/content/sasdummy/2012/12/18/using-sas-to-access-data-stored-on-dropbox/
Or is it possible to %INCLUDE a file directly from SAS Support website or GitHub?
The macros and macro variables are in the SAS sample library, which is available on the web, from the SAS help in display manager (for most releases I believe), and from the HTML documentation in newer releases. The DATA step copies them from the web location. All you have to do is a one-time copy, paste, and run of the lines from the chapter to make a local copy of the file. From then on you can just include it. The only thing I planned for was putting them in the sample library.
@WarrenKuhfeld wrote:
and from the HTML documentation in newer releases.
It seems to link back to the older style of formatting on the web, from the 'newer' style which is cleaner to copy/paste from, ergo my question.
STAT 14.3 Documentation
Links to this as source code, much different style than the newer versions:
http://support.sas.com/documentation/onlinedoc/stat/ex_code/142/templft.html
PS. It seems we've come full circle in some ways, originally had FTP sites with just plain text files, then migrated to web pages instead and now back to text files 🙂
Ah, okay. Sadly my SAS classes skipped over macros, so I had no idea you had to actually add them to your program, which makes a lot more sense. Will try this then circle back. Thanks!
1. Run the code to create the macros on your system.
http://support.sas.com/documentation/onlinedoc/stat/ex_code/142/templft.html
Or an easy to copy version here:
2. An example of how you would modify it, in this case, I modified to show 0 to 500 by 100. You no longer need the MAXTIME option.
%ProvideSurvivalMacros;
%let xOptions = label="Time"
linearopts=(viewmin=0 viewmax=500
tickvaluelist=(0 100 200 300 400 500));
%CompileSurvivalTemplates;
proc lifetest data=VALung plots=(s) outtest=Test;
time SurvTime*Censor(1);
id Therapy;
strata Cell;
test Age Prior DiagTime Kps Treatment;
run;
Data to run the code above is available here as well:
http://documentation.sas.com/api/docsets/statug/14.3/content/statug_code_liftex1.htm?locale=en
Thanks for your answer. I ran the first macro exactly as stated, then added in
%ProvideSurvivalMacros;
%let xOptions = label="Time"
linearopts=(viewmin=0 viewmax=24
tickvaluelist=(0 6 12 18 24));
%CompileSurvivalTemplates;
libname lvad 'd:\lvad';
Options nofmterr;
proc lifetest data=lvad.inf4 method=life plots=survival(cl cb=hw strata=panel)
plots=hazard(cl) intervals = (0 to 24 by 1);
time Months*inf_ind(0);
run;
And there was no change, the resulting graph was exactly the same. I tried several similar macros and nothing worked. I've never successfully used a macro ever, am I doing something wrong?
Post your log from when you run the PROC LIFETEST code please.
Also, try running the demo code I provided with the source data and see if that generates the expected graph. If it does, it's something with your code or data. If it doesn't then it's something with the answer or SAS version.
@zombiegirl wrote:
Thanks for your answer. I ran the first macro exactly as stated, then added in
%ProvideSurvivalMacros; %let xOptions = label="Time" linearopts=(viewmin=0 viewmax=24 tickvaluelist=(0 6 12 18 24)); %CompileSurvivalTemplates; libname lvad 'd:\lvad'; Options nofmterr; proc lifetest data=lvad.inf4 method=life plots=survival(cl cb=hw strata=panel) plots=hazard(cl) intervals = (0 to 24 by 1); time Months*inf_ind(0); run;
And there was no change, the resulting graph was exactly the same. I tried several similar macros and nothing worked. I've never successfully used a macro ever, am I doing something wrong?
Registration is now open for SAS Innovate 2025 , our biggest and most exciting global event of the year! Join us in Orlando, FL, May 6-9.
Sign up by Dec. 31 to get the 2024 rate of just $495.
Register now!
Learn the difference between classical and Bayesian statistical approaches and see a few PROC examples to perform Bayesian analysis in this video.
Find more tutorials on the SAS Users YouTube channel.
Ready to level-up your skills? Choose your own adventure.