Hi everyone. I'm trying to add an at-risk table to my Kaplan-Meier curves. I'm using the survival macros code found here.
If I do not use the "outside" option, everything aligns nicely.
* Bring in macro; %ProvideSurvivalMacros %let tatters = textattrs=(size=14pt); %let TitleText0 = "3-Year Post-Recurrence Survival" / textattrs=(size=14pt); %let TitleText1 = &titletext0 ; %let TitleText2 = &titletext0 ; %let yoptions = label='Overall Survival Probability' labelattrs=(size=12pt) linearopts=(viewmin=0 viewmax=1 tickvaluelist=(0 .2 0.4 0.6 0.8 1)); %let xoptions = label='Months from Recurrence' labelattrs=(size=12pt) linearopts=(viewmin=0 viewmax=24 tickvaluelist=(0 6 12 18 24));; %let StepOpts = lineattrs=(thickness=1); %let LegendOpts = title=' ' location=inside across=1 autoalign=(TopRight) border=FALSE; %let GraphOpts = attrpriority=none DataLinePatterns=(Solid); * 24-Apr-2024: Add number at risk; %let AtRiskOpts = valueattrs=(size=10pt) ; %CompileSurvivalTemplates; ods select survivalplot; proc lifetest data=post plots=survival(atrisk(maxlen=20 /*outside*/)=0 to 24 by 6); format group $recur_two.; time PRS3YrMonths*death3yr(0); strata group; run; ods select all;
However, if I request it to be outside the plot area, it is no longer aligned.
* Bring in macro; %ProvideSurvivalMacros %let tatters = textattrs=(size=14pt); %let TitleText0 = "3-Year Post-Recurrence Survival" / textattrs=(size=14pt); %let TitleText1 = &titletext0 ; %let TitleText2 = &titletext0 ; %let yoptions = label='Overall Survival Probability' labelattrs=(size=12pt) linearopts=(viewmin=0 viewmax=1 tickvaluelist=(0 .2 0.4 0.6 0.8 1)); %let xoptions = label='Months from Recurrence' labelattrs=(size=12pt) linearopts=(viewmin=0 viewmax=24 tickvaluelist=(0 6 12 18 24));; %let StepOpts = lineattrs=(thickness=1); %let LegendOpts = title=' ' location=inside across=1 autoalign=(TopRight) border=FALSE; %let GraphOpts = attrpriority=none DataLinePatterns=(Solid); * 24-Apr-2024: Add number at risk; %let AtRiskOpts = valueattrs=(size=10pt) ; %CompileSurvivalTemplates; ods select survivalplot; proc lifetest data=post plots=survival(atrisk(maxlen=20 outside)=0 to 24 by 6); format group $recur_two.; time PRS3YrMonths*death3yr(0); strata group; run; ods select all;
In the macro code, while messing around with the AtRiskLattice sections to try and fix it, I removed "xaxisopts=(display=none)." This did not fix it, but did illuminate the issue a bit. Apparently the axis for the at-risk table is not the same as the overall x-axis:
Does anyone have any idea how to get these to align?
Please let me know if I can provide more info.
You could try alternative way to get it .
proc format;
value grpLabel 1='ALL' 2='AML low risk' 3='AML high risk';
run;
data BMT;
input DIAGNOSIS Ftime Status Gender@@;
label Ftime="Days";
format Diagnosis grpLabel.;
datalines;
1 2081 0 1 1 1602 0 1
1 1496 0 1 1 1462 0 0
1 1433 0 1 1 1377 0 1
1 1330 0 1 1 996 0 1
1 226 0 0 1 1199 0 1
1 1111 0 1 1 530 0 1
1 1182 0 0 1 1167 0 0
1 418 2 1 1 383 1 1
1 276 2 0 1 104 1 1
1 609 1 1 1 172 2 0
1 487 2 1 1 662 1 1
1 194 2 0 1 230 1 0
1 526 2 1 1 122 2 1
1 129 1 0 1 74 1 1
1 122 1 0 1 86 2 1
1 466 2 1 1 192 1 1
1 109 1 1 1 55 1 0
1 1 2 1 1 107 2 1
1 110 1 0 1 332 2 1
2 2569 0 1 2 2506 0 1
2 2409 0 1 2 2218 0 1
2 1857 0 0 2 1829 0 1
2 1562 0 1 2 1470 0 1
2 1363 0 1 2 1030 0 0
2 860 0 0 2 1258 0 0
2 2246 0 0 2 1870 0 0
2 1799 0 1 2 1709 0 0
2 1674 0 1 2 1568 0 1
2 1527 0 0 2 1324 0 1
2 957 0 1 2 932 0 0
2 847 0 1 2 848 0 1
2 1850 0 0 2 1843 0 0
2 1535 0 0 2 1447 0 0
2 1384 0 0 2 414 2 1
2 2204 2 0 2 1063 2 1
2 481 2 1 2 105 2 1
2 641 2 1 2 390 2 1
2 288 2 1 2 421 1 1
2 79 2 0 2 748 1 1
2 486 1 0 2 48 2 0
2 272 1 0 2 1074 2 1
2 381 1 0 2 10 2 1
2 53 2 0 2 80 2 0
2 35 2 0 2 248 1 1
2 704 2 0 2 211 1 1
2 219 1 1 2 606 1 1
3 2640 0 1 3 2430 0 1
3 2252 0 1 3 2140 0 1
3 2133 0 0 3 1238 0 1
3 1631 0 1 3 2024 0 0
3 1345 0 1 3 1136 0 1
3 845 0 0 3 422 1 0
3 162 2 1 3 84 1 0
3 100 1 1 3 2 2 1
3 47 1 1 3 242 1 1
3 456 1 1 3 268 1 0
3 318 2 0 3 32 1 1
3 467 1 0 3 47 1 1
3 390 1 1 3 183 2 0
3 105 2 1 3 115 1 0
3 164 2 0 3 93 1 0
3 120 1 0 3 80 2 1
3 677 2 1 3 64 1 0
3 168 2 0 3 74 2 0
3 16 2 0 3 157 1 0
3 625 1 0 3 48 1 0
3 273 1 1 3 63 2 1
3 76 1 1 3 113 1 0
3 363 2 1
;
run;
ods select none;
ods output SurvivalPlot=SurvivalPlot;
proc lifetest data=bmt plots=survival(atrisk=0 to 2500 by 500);
time ftime*Status(0);
strata diagnosis;
run;
ods select all;
title '缓解概率';
proc sgplot data=SurvivalPlot;
step x=Time y=Survival / group=Stratum lineattrs=(pattern=solid) name='a' ;
scatter x=Time y=Censored /group=Stratum markerattrs=(symbol=plus ) ;
xaxistable atrisk / x=tatrisk class=stratum colorgroup=stratum valueattrs=(weight=bold);
xaxis label='天数';
yaxis label='存活概率';
keylegend 'a' / across=1 location=inside position=ne title='' ;
inset '+ Censored' / position=sw border;
run;
You could try alternative way to get it .
proc format;
value grpLabel 1='ALL' 2='AML low risk' 3='AML high risk';
run;
data BMT;
input DIAGNOSIS Ftime Status Gender@@;
label Ftime="Days";
format Diagnosis grpLabel.;
datalines;
1 2081 0 1 1 1602 0 1
1 1496 0 1 1 1462 0 0
1 1433 0 1 1 1377 0 1
1 1330 0 1 1 996 0 1
1 226 0 0 1 1199 0 1
1 1111 0 1 1 530 0 1
1 1182 0 0 1 1167 0 0
1 418 2 1 1 383 1 1
1 276 2 0 1 104 1 1
1 609 1 1 1 172 2 0
1 487 2 1 1 662 1 1
1 194 2 0 1 230 1 0
1 526 2 1 1 122 2 1
1 129 1 0 1 74 1 1
1 122 1 0 1 86 2 1
1 466 2 1 1 192 1 1
1 109 1 1 1 55 1 0
1 1 2 1 1 107 2 1
1 110 1 0 1 332 2 1
2 2569 0 1 2 2506 0 1
2 2409 0 1 2 2218 0 1
2 1857 0 0 2 1829 0 1
2 1562 0 1 2 1470 0 1
2 1363 0 1 2 1030 0 0
2 860 0 0 2 1258 0 0
2 2246 0 0 2 1870 0 0
2 1799 0 1 2 1709 0 0
2 1674 0 1 2 1568 0 1
2 1527 0 0 2 1324 0 1
2 957 0 1 2 932 0 0
2 847 0 1 2 848 0 1
2 1850 0 0 2 1843 0 0
2 1535 0 0 2 1447 0 0
2 1384 0 0 2 414 2 1
2 2204 2 0 2 1063 2 1
2 481 2 1 2 105 2 1
2 641 2 1 2 390 2 1
2 288 2 1 2 421 1 1
2 79 2 0 2 748 1 1
2 486 1 0 2 48 2 0
2 272 1 0 2 1074 2 1
2 381 1 0 2 10 2 1
2 53 2 0 2 80 2 0
2 35 2 0 2 248 1 1
2 704 2 0 2 211 1 1
2 219 1 1 2 606 1 1
3 2640 0 1 3 2430 0 1
3 2252 0 1 3 2140 0 1
3 2133 0 0 3 1238 0 1
3 1631 0 1 3 2024 0 0
3 1345 0 1 3 1136 0 1
3 845 0 0 3 422 1 0
3 162 2 1 3 84 1 0
3 100 1 1 3 2 2 1
3 47 1 1 3 242 1 1
3 456 1 1 3 268 1 0
3 318 2 0 3 32 1 1
3 467 1 0 3 47 1 1
3 390 1 1 3 183 2 0
3 105 2 1 3 115 1 0
3 164 2 0 3 93 1 0
3 120 1 0 3 80 2 1
3 677 2 1 3 64 1 0
3 168 2 0 3 74 2 0
3 16 2 0 3 157 1 0
3 625 1 0 3 48 1 0
3 273 1 1 3 63 2 1
3 76 1 1 3 113 1 0
3 363 2 1
;
run;
ods select none;
ods output SurvivalPlot=SurvivalPlot;
proc lifetest data=bmt plots=survival(atrisk=0 to 2500 by 500);
time ftime*Status(0);
strata diagnosis;
run;
ods select all;
title '缓解概率';
proc sgplot data=SurvivalPlot;
step x=Time y=Survival / group=Stratum lineattrs=(pattern=solid) name='a' ;
scatter x=Time y=Censored /group=Stratum markerattrs=(symbol=plus ) ;
xaxistable atrisk / x=tatrisk class=stratum colorgroup=stratum valueattrs=(weight=bold);
xaxis label='天数';
yaxis label='存活概率';
keylegend 'a' / across=1 location=inside position=ne title='' ;
inset '+ Censored' / position=sw border;
run;
Thanks so much! That worked. I have spent so much time on previous projects trying to get the macro to work - using SGPLOT is sooo much easier!
Here's what I ultimately used:
* Save output to dataset; ods select none; proc lifetest data=post plots=survival(atrisk(maxlen=20)=0 to 24 by 6); format group $recur_two.; time PRS3YrMonths*death3yr(0); strata group; ods output survivalplot=postplot; run; ods select all; * Only keep <=24 months; data postplot2; set postplot; if tatrisk <= 24; run; title height=14pt 'Post-recurrence Survival' ; proc sgplot data=postplot2; step x=Time y=Survival / group=Stratum lineattrs=(pattern=solid) name='a' ; scatter x=Time y=Censored /group=Stratum markerattrs=(symbol=plus ) ; xaxistable atrisk / x=tatrisk class=stratum colorgroup=stratum valueattrs=(size=10pt) ; xaxis label='Months from Recurrence' values=(0 6 12 18 24) labelattrs=(size=12pt) valueattrs=(size=10pt); yaxis label='Overall Survival Probability' labelattrs=(size=12pt) valueattrs=(size=10pt); keylegend 'a' / across=1 location=inside position=ne title='' ; inset '+ Censored' / position=sw border; run; title;
And the output:
Join us for SAS Innovate 2025, our biggest and most exciting global event of the year, in Orlando, FL, from May 6-9.
Early bird rate extended! Save $200 when you sign up by March 31.
Learn how use the CAT functions in SAS to join values from multiple variables into a single value.
Find more tutorials on the SAS Users YouTube channel.
Ready to level-up your skills? Choose your own adventure.