BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
Denali
Quartz | Level 8

Hi,

 

I would like to create a Kaplan-Mier Plot with x-axis starting at Year 5 instead of Year 0 because all my patients have survived at least 5 years. I do not want to present the flat line from Year 0 to Year 5. Below is my code and could anyone please tell me how to make the x-axis starting at 5 instead of 0?  Thank you!

 


ods graphics on / width = 6 in height = in border = off ;
ods graphics on/ imagefmt = tiff imagename = "Figure_AKI_Survivors" reset = index;
ods listing image_dpi = 300 style = axis_wall style=StatColor;

 

proc lifetest data=two plots=survival(test atrisk =5 to 15 by 2.5)
/* ods select SurvivalPlot;*/
outsur=survival2;
time Survive_year*death(0);
label Survive_year='Time (Years)';
strata AKI;
ods output SurvivalPlot = graph;
run;
ods graphics off;

1 ACCEPTED SOLUTION

Accepted Solutions
Reeza
Super User

Here's the example from the blog with the timeline starts from 500 instead of 0.

The XAXIS statement controls the axis limits and graphs. 

You can uncomment the XAXISTABLE if you want the table at the bottom as well. 

 

%let gpath=/folders/myfolders/;

%let w=5in;
%let h=3in;
%let dpi=300;


/*--This sample uses data from sample 49_2_1--*/
proc format;
   value risk 1='ALL' 2='AML-Low Risk' 3='AML-High Risk';

/*--Data for proc LIFETEST sample 49_2_1--*/
data BMT;
   input Group T Status @@;
   format Group risk.;
   label T='Disease Free Time';
   datalines;
1 2081 0 1 1602 0 1 1496 0 1 1462 0 1 1433 0
1 1377 0 1 1330 0 1  996 0 1  226 0 1 1199 0
1 1111 0 1  530 0 1 1182 0 1 1167 0 1  418 1
1  383 1 1  276 1 1  104 1 1  609 1 1  172 1
1  487 1 1  662 1 1  194 1 1  230 1 1  526 1
1  122 1 1  129 1 1   74 1 1  122 1 1   86 1
1  466 1 1  192 1 1  109 1 1   55 1 1    1 1
1  107 1 1  110 1 1  332 1 2 2569 0 2 2506 0
2 2409 0 2 2218 0 2 1857 0 2 1829 0 2 1562 0
2 1470 0 2 1363 0 2 1030 0 2  860 0 2 1258 0
2 2246 0 2 1870 0 2 1799 0 2 1709 0 2 1674 0
2 1568 0 2 1527 0 2 1324 0 2  957 0 2  932 0
2  847 0 2  848 0 2 1850 0 2 1843 0 2 1535 0
2 1447 0 2 1384 0 2  414 1 2 2204 1 2 1063 1
2  481 1 2  105 1 2  641 1 2  390 1 2  288 1
2  421 1 2   79 1 2  748 1 2  486 1 2   48 1
2  272 1 2 1074 1 2  381 1 2   10 1 2   53 1
2   80 1 2   35 1 2  248 1 2  704 1 2  211 1
2  219 1 2  606 1 3 2640 0 3 2430 0 3 2252 0
3 2140 0 3 2133 0 3 1238 0 3 1631 0 3 2024 0
3 1345 0 3 1136 0 3  845 0 3  422 1 3  162 1
3   84 1 3  100 1 3    2 1 3   47 1 3  242 1
3  456 1 3  268 1 3  318 1 3   32 1 3  467 1
3   47 1 3  390 1 3  183 1 3  105 1 3  115 1
3  164 1 3   93 1 3  120 1 3   80 1 3  677 1
3   64 1 3  168 1 3   74 1 3   16 1 3  157 1
3  625 1 3   48 1 3  273 1 3   63 1 3   76 1
3  113 1 3  363 1
;
run;

/*--Get survival plot data from LIFETEST procedure--*/
ods select none;
ods output Survivalplot=SurvivalPlotData;
proc lifetest data=BMT plots=survival(atrisk=0 to 2500 by 500);
   time T * Status(0);
   strata Group / test=logrank adjust=sidak;
run;
ods select all;


/*--Survival Plot with outer Risk Table using AxisTable--*/

ods graphics / reset width=5in height=3in ;
title 'Product-Limit Survival Estimates';
title2  h=0.8 'With Number of Subjects at Risk';
footnote j=l h=6pt italic 'This visual is for discussion of graph features only.'  
         '  The actual details should be customized by user to suit their application.';
proc sgplot data=SurvivalPlotData noborder;
  step x=time y=survival / group=stratum name='s';
  scatter x=time y=censored / markerattrs=(symbol=plus) name='c';
  scatter x=time y=censored / markerattrs=(symbol=plus) GROUP=stratum;
  *xaxistable atrisk / x=tatrisk class=stratum colorgroup=stratum valueattrs=(weight=bold);
  keylegend 'c' / location=inside position=topright;
  keylegend 's' / linelength=20;
  *controls the graph axis;
  xaxis values=(500 to 2500 by 500);
run;

View solution in original post

14 REPLIES 14
Reeza
Super User
Do you need to truncate the graph or just change the x axis to start at 0? Two very different things.
Denali
Quartz | Level 8

I need to change the x-axis to start at year 5 instead of starting at 0.

Denali
Quartz | Level 8

Because nobody died at year 0-5 and they started dying from year 5-15. So I am hoping not to show year 0-5 in the graph.

Reeza
Super User

Sounds like you want it truncated. I see two options, subtract 5 from your time and then format the x axis (proc format) to show the actual time. 

 

Or build a custom plot by capturing the data from LIFETEST.

https://blogs.sas.com/content/graphicallyspeaking/2018/02/19/survival-plot-twist-using-sgplot-proced...

 

The blog post shows how to graph it, you can customize the XAXIS statement. 

 

You capture your data by adding the following line before the code. 

 

ods output survivalPlotData = survGraphData;

*your proc lifetest code;
Denali
Quartz | Level 8

For option 1, I substracted 5 for time (year) variable:

 

data two_a;
set two;
KM_year = survive_year - 5;
run;

 

How do I format it back to the real number? All the numbers are with many decimal now. Please see below output:

KM_year
8.6110
11.1041
10.3452
7.3644
4.7753
11.8055
0.9507
4.5096
1.5123
11.4164
7.2548
11.2082
8.9123
3.6082
11.0055
6.6795
6.5233
2.9863
0.6438
2.7890
7.2740
1.2795

Thank you!

 

Reeza
Super User
Create a format and apply it to the axis. You may need to modify the template (check the macros in the documentation).
https://documentation.sas.com/?docsetId=statug&docsetTarget=statug_kaplan_toc.htm&docsetVersion=15.1...

Although it seems harder, the SGPLOT is actually the easier solution here.
Denali
Quartz | Level 8

I am attachinig my graph on the post. 

 

I am looking at the page of "Modifying the Axis": https://go.documentation.sas.com/?docsetId=statug&docsetTarget=statug_kaplan_sect016.htm&docsetVersi...

 


%ProvideSurvivalMacros

%let yOptions = label="Survival"
linearopts=(viewmin=0 viewmax=1;
%let xOptions = label="Survival Year"
linearopts=(viewmin=5 viewmax=20
tickvaluelist=(5 10 15 20));

%CompileSurvivalTemplates

proc lifetest data=two plots=survival(cb=hw test);
time Survive_year*death(0);
strata AKI;
run;

 

But this is only for changing the ticks, not the X axis starting point. I still don't know how to do it....... 

Reeza
Super User

Did you try the ODS and SGPLOT approach?

 

1. Run PROC LIFETEST with the modification I suggested

2. Copy and paste code from blog post, change variable names to match yours

3. Ensure graph matches output from PROC LIFETEST

4. Change Axis using an XAXIS notation.

 

Those are the steps you need to follow. It's exactly what I would do if I was trying to make an example for you to follow.

Denali
Quartz | Level 8

Hi,

 

I ran below code per your suggestion:


ods output survivalPlotData = survGraphData;
proc lifetest data=two plots=survival ;
time Survive_year*death(0);
strata AKI;
run;

 

But it gave me the error message:

 


NOTE: The LOGLOG transform is used to compute the confidence limits for the quartiles of the
survivor distribution. To suppress using this transform, specify CONFTYPE=LINEAR in the
PROC LIFETEST statement.
NOTE: Graph's name, LIFETEST, changed to LIFETES1. LIFETEST is already used or not a valid SAS
name.
NOTE: Graph's name, LIFETEST, changed to LIFETES1. LIFETEST is already used or not a valid SAS
name.
NOTE: 29352 bytes written to C:\Users\LinI1\AppData\Local\Temp\SAS Temporary
Files\_TD7508_WBSTE046_\lifetest1.png.
WARNING: Output 'survivalPlotData' was not created. Make sure that the output object name,
label, or path is spelled correctly. Also, verify that the appropriate procedure
options are used to produce the requested output object. For example, verify that
the NOPRINT option is not used.
NOTE: PROCEDURE LIFETEST used (Total process time):
real time 0.56 seconds
cpu time 0.46 seconds

 

Reeza
Super User
If you download the code in the blog post referenced it has the fully worked example INCLUDING the PROC LIFETEST portion and the graphing code. It's at the bottom of the page.

There was a mistake in my code, I added the word DATA to the , it should be:
ods output survivalplot = survivalplotData;


ods output Survivalplot=SurvivalPlotData;
Reeza
Super User

Here's the example from the blog with the timeline starts from 500 instead of 0.

The XAXIS statement controls the axis limits and graphs. 

You can uncomment the XAXISTABLE if you want the table at the bottom as well. 

 

%let gpath=/folders/myfolders/;

%let w=5in;
%let h=3in;
%let dpi=300;


/*--This sample uses data from sample 49_2_1--*/
proc format;
   value risk 1='ALL' 2='AML-Low Risk' 3='AML-High Risk';

/*--Data for proc LIFETEST sample 49_2_1--*/
data BMT;
   input Group T Status @@;
   format Group risk.;
   label T='Disease Free Time';
   datalines;
1 2081 0 1 1602 0 1 1496 0 1 1462 0 1 1433 0
1 1377 0 1 1330 0 1  996 0 1  226 0 1 1199 0
1 1111 0 1  530 0 1 1182 0 1 1167 0 1  418 1
1  383 1 1  276 1 1  104 1 1  609 1 1  172 1
1  487 1 1  662 1 1  194 1 1  230 1 1  526 1
1  122 1 1  129 1 1   74 1 1  122 1 1   86 1
1  466 1 1  192 1 1  109 1 1   55 1 1    1 1
1  107 1 1  110 1 1  332 1 2 2569 0 2 2506 0
2 2409 0 2 2218 0 2 1857 0 2 1829 0 2 1562 0
2 1470 0 2 1363 0 2 1030 0 2  860 0 2 1258 0
2 2246 0 2 1870 0 2 1799 0 2 1709 0 2 1674 0
2 1568 0 2 1527 0 2 1324 0 2  957 0 2  932 0
2  847 0 2  848 0 2 1850 0 2 1843 0 2 1535 0
2 1447 0 2 1384 0 2  414 1 2 2204 1 2 1063 1
2  481 1 2  105 1 2  641 1 2  390 1 2  288 1
2  421 1 2   79 1 2  748 1 2  486 1 2   48 1
2  272 1 2 1074 1 2  381 1 2   10 1 2   53 1
2   80 1 2   35 1 2  248 1 2  704 1 2  211 1
2  219 1 2  606 1 3 2640 0 3 2430 0 3 2252 0
3 2140 0 3 2133 0 3 1238 0 3 1631 0 3 2024 0
3 1345 0 3 1136 0 3  845 0 3  422 1 3  162 1
3   84 1 3  100 1 3    2 1 3   47 1 3  242 1
3  456 1 3  268 1 3  318 1 3   32 1 3  467 1
3   47 1 3  390 1 3  183 1 3  105 1 3  115 1
3  164 1 3   93 1 3  120 1 3   80 1 3  677 1
3   64 1 3  168 1 3   74 1 3   16 1 3  157 1
3  625 1 3   48 1 3  273 1 3   63 1 3   76 1
3  113 1 3  363 1
;
run;

/*--Get survival plot data from LIFETEST procedure--*/
ods select none;
ods output Survivalplot=SurvivalPlotData;
proc lifetest data=BMT plots=survival(atrisk=0 to 2500 by 500);
   time T * Status(0);
   strata Group / test=logrank adjust=sidak;
run;
ods select all;


/*--Survival Plot with outer Risk Table using AxisTable--*/

ods graphics / reset width=5in height=3in ;
title 'Product-Limit Survival Estimates';
title2  h=0.8 'With Number of Subjects at Risk';
footnote j=l h=6pt italic 'This visual is for discussion of graph features only.'  
         '  The actual details should be customized by user to suit their application.';
proc sgplot data=SurvivalPlotData noborder;
  step x=time y=survival / group=stratum name='s';
  scatter x=time y=censored / markerattrs=(symbol=plus) name='c';
  scatter x=time y=censored / markerattrs=(symbol=plus) GROUP=stratum;
  *xaxistable atrisk / x=tatrisk class=stratum colorgroup=stratum valueattrs=(weight=bold);
  keylegend 'c' / location=inside position=topright;
  keylegend 's' / linelength=20;
  *controls the graph axis;
  xaxis values=(500 to 2500 by 500);
run;
Denali
Quartz | Level 8

Hi, 

 

This actually worked!!! THANK YOU!!!

 

But there is 2 more things that I am trying to accomplish: 

 

1. How to add "log rank p" under "+Censor"?

 

2. I also tried to add "AKI" as my group name for the legend (before No ----- and Yes ----)-

I thougt the " label stratum = AKI;"  or "keylegend 'No' 'Yes' / title="AKI"; " would add "AKI"but it did not.


/*--Get survival plot data from LIFETEST procedure--*/
ods select none;
ods output Survivalplot=SurvivalPlotData;
proc lifetest data=two plots=survival(atrisk=5 to 20 by 2.5);
time Survive_year * death(0);
strata AKI;
run;
ods select all;

/*--Survival Plot with outer Risk Table using AxisTable--*/

ods graphics / reset width=5in height=3in ;
title 'Product-Limit Survival Estimates';
title2 h=0.8 'With Number of Subjects at Risk';
ods listing gpath= "H:\Biostatistics\Ihsin\Subspecialty Medicine\Renal Service\Latcha,Sheron\SAS Program" image_dpi=300 ;
ods graphics on/ imagefmt = tiff imagename = "Figure_AKI_Survivor_5yr" reset = index;
proc sgplot data=SurvivalPlotData noborder;
step x=time y=survival / group=stratum name='s';
scatter x=time y=censored / markerattrs=(symbol=plus) name='c';
scatter x=time y=censored / markerattrs=(symbol=plus) GROUP=stratum;
xaxistable atrisk / x=tatrisk location=inside class=stratum colorgroup=stratum valueattrs=(weight=bold);
keylegend 'c' / location=inside position=topright;
keylegend 's' / linelength=20;
keylegend 'No' 'Yes' / title="AKI";
*controls the graph axis;
xaxis values=(5 to 20 by 5);
yaxis values=(0 to 1 by .2);
label time = Time (Year) stratum = AKI;
run;

enatx
Calcite | Level 5

@Denali wrote:

Hi,

 

I would like to create a Kaplan-Mier Plot with x-axis starting at Year 5 instead of Year 0 because all my patients have survived at least 5 years. I do not want to present the flat line from Year 0 to Year 5. Below is my code and could anyone please tell me how to make the x-axis about starting at 5 instead of 0?  Thank you!

 


ods graphics on / width = 6 in height = in border = off ;
ods graphics on/ imagefmt = tiff imagename = "Figure_AKI_Survivors" reset = index;
ods listing image_dpi = 300 style = axis_wall style=StatColor;

 

proc lifetest data=two plots=survival(test atrisk =5 to 15 by 2.5)
/* ods select SurvivalPlot;*/
outsur=survival2;
time Survive_year*death(0);
label Survive_year='Time (Years)';
strata AKI;
ods output SurvivalPlot = graph;
run;
ods graphics off;


I am having difficulty adjusting the X-axis range for a survival plot using PROC LIFETEST

 

Rather than starting at "0", I want to start at "12000" instead by intervals of "1000"

any solution ?

Reeza
Super User

@enatx Change the XAXIS statement in the solution I posted. 

If it doesn't work, show your code. 

SAS Innovate 2025: Save the Date

 SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!

Save the date!

How to Concatenate Values

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.

SAS Training: Just a Click Away

 Ready to level-up your skills? Choose your own adventure.

Browse our catalog!

Discussion stats
  • 14 replies
  • 6554 views
  • 1 like
  • 3 in conversation