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

Hello,

I've received my first project at work to  make a Kaplan Meier curve. The question is " 5 & 10 year survival" for EndStage Heart Failure.

 

The categories given to me are:

Name

MRN

Gender

DOB

Date EndStage

Death=1, Alive at last Follow Up=0     [I made this my status variable and labeled it "Status" in my dataset]

Date of Last Visit

FU ES

Date Death

Adverse events prior to ES

time to nonfatal adverse event

Time transplant to Death

Time of Follow-up or to death    [I made this my time variable and labeled it "FU_ES" in my dataset]

Date of last visit, living

 

My code is as follows:

 

libname Hetal "\\tuftsmc\home\hpatel3\SAS Datasets";

run;

proc import out=hetal.ES_database datafile="\\tuftsmc\home\hpatel3\SAS Datasets\ES Database Edit.csv" dbms=csv replace; getnames=yes; datarow=2;

run;

ods graphics on;

 

proc lifetest data=hetal.es_database conftype=loglog plot=(s) plots=(survival(atrisk=0 to 10 by 5 test));

 

time FU_ES*Status(0);

survival out=survci;

Title " 5 & 10 year Survival for ES";

run;

 

 

I just have absolutely no idea if I've done this correctly. Is the atrisk correct? Does the Product Limit Survival Estimate look...ok? is there only a 25% Quartile for the 95% CI because of the censored variables? HELP. Also attaching my results.

1 ACCEPTED SOLUTION

Accepted Solutions
JeffMeyers
Barite | Level 11

Hello,

    I was tagged in this conversation so I thought I'd chip in here.  Your code is mostly correct, but if you're trying to find the 5 and 10 year survival rates then I would change it to be this:

 

proc lifetest data=hetal.es_database conftype=loglog plot=(s) plots=(survival)

   TIMELIST=5 10 outs=survival_rates reduceout;

 

time FU_ES*Status(0);

run;

 

This will give you a dataset (survival_rates) that has the 5 and 10 year (assuming your time variable is in years) estimates and confidence bounds.  If your time scale is not in years you will have to convert it before using proc lifetest.

 

The reason the medians (or confidence bounds) might not be evaluable is that the curve needs to cross the 50% survival threshold to have a median.  The curve's upper CI bound has to cross 50% survival for the median's upper ci and the curve's lower CI bound has to cross 50% survival for the median's lower ci.  Your curve just barely clips through the 50% survival so it wouldn't be able to have the 75% quartile nor the upper ci for your median.

 

If you want to run NEWSURV to give you the curve with the estimates in the graph you would use the following macro call (after initializing the macro code):

%newsurv(data=hetal.es_database,time=FU_ES,cens=Status,cen_vl=0,summary=0, timelist=5 10, timedx=years);

 

The macro defaults to loglog for confidence interval type so you wouldn't have to worry about that.  You could add in ylabel and xlabel options to change those.

View solution in original post

10 REPLIES 10
BeverlyBrown
Community Manager

Hi @hpatel3, this article by @JeffMeyers, Kaplan-Meier Survival Plotting Macro %NEWSURV, and items in this user's guide may be useful. @WarrenKuhfeld, anything you'd add?

Couldn't attend SAS Innovate in person? We gotchu. Access on-demand content now!

hpatel3
Obsidian | Level 7

Hi @BeverlyBrown, does that mean I've done my graph wrong? Thank you for the extra resources, I'll definitely be perusing them! 🙂

BeverlyBrown
Community Manager

Oh, you wouldn't want me critiquing your graph! I'm a resource finder/connector, which is why I replied with links to docs and tagged Jeff and Warren. Hoping one of them or another expert will reply shortly.

Couldn't attend SAS Innovate in person? We gotchu. Access on-demand content now!

WarrenKuhfeld
Rhodochrosite | Level 12
Every thing I know about the KM plot, I put in that chapter. On the road now without computer access.
JeffMeyers
Barite | Level 11

Hello,

    I was tagged in this conversation so I thought I'd chip in here.  Your code is mostly correct, but if you're trying to find the 5 and 10 year survival rates then I would change it to be this:

 

proc lifetest data=hetal.es_database conftype=loglog plot=(s) plots=(survival)

   TIMELIST=5 10 outs=survival_rates reduceout;

 

time FU_ES*Status(0);

run;

 

This will give you a dataset (survival_rates) that has the 5 and 10 year (assuming your time variable is in years) estimates and confidence bounds.  If your time scale is not in years you will have to convert it before using proc lifetest.

 

The reason the medians (or confidence bounds) might not be evaluable is that the curve needs to cross the 50% survival threshold to have a median.  The curve's upper CI bound has to cross 50% survival for the median's upper ci and the curve's lower CI bound has to cross 50% survival for the median's lower ci.  Your curve just barely clips through the 50% survival so it wouldn't be able to have the 75% quartile nor the upper ci for your median.

 

If you want to run NEWSURV to give you the curve with the estimates in the graph you would use the following macro call (after initializing the macro code):

%newsurv(data=hetal.es_database,time=FU_ES,cens=Status,cen_vl=0,summary=0, timelist=5 10, timedx=years);

 

The macro defaults to loglog for confidence interval type so you wouldn't have to worry about that.  You could add in ylabel and xlabel options to change those.

hpatel3
Obsidian | Level 7

@JeffMeyers Alright, Timelist worked great and I got my rates. Thank you!

 

My other question is, if I want to format my graph (remove the tick marks completely, remove the x-axis label completely, label the y-axis, make it "journal" quality, etc) --is there a data step within proc lifetest that will do it?

 

I'm familiar with just using proc sgplot to define the characteristics of my graph, is there anything similar to it that isn't macro (it seems to be not reading correctly for me)

 

EXAMPLE

 

PROC sgplot ex.PNG

 

Thank you!

 

JeffMeyers
Barite | Level 11

I think Warren has some macros to modify the template for the LIFETEST procedure, but in all honesty it'll probably be faster if you just output the plot dataset and make your own SGPLOT.

ODS OUTPUT SURVIVALPLOT=survplot;
PROC LIFETEST....
**Your code here**
run;

If you have ODS graphics on, then the dataset that LIFETEST uses to make the graph will be saved into the dataset survplot, which you can then feed into SGPLOT to make it look as you wish.

hpatel3
Obsidian | Level 7

I have my ODS graphics on, and my Looks like this:

 

 

 sgplot.PNG

 

and the results I'm getting are, unfortunately, what I've been getting all day. My SGPlot looks nothing like my survival plot, I feel like I'm missing some silly step in the middle that gives me the data.  If I Can just get my data to show up on here like it does in my Proc Test,  I think I'll be golden for moving forward on the rest of my similar projects.

 

 

 

sgplot.PNG

 

 

 

JeffMeyers
Barite | Level 11
Your SGPLOT is referring to your original data instead of the survplot dataset. Your original data doesn't have any survival calculations. You need to use the dataset that came from lifetest (survplot) with its variables to recreate the survival plot.
JeffMeyers
Barite | Level 11

Here's an example using the sashelp.bmt dataset:

 


ods output survivalplot=survplot;
proc lifetest data=sashelp.bmt;
  time t*status(0);
run;

 ods graphics / reset;
proc sgplot data=survplot;
   step x=time y=survival / lineattrs=(color=black pattern=1);
   scatter x=time y=censored / markerattrs=(symbol=plus color=black);
   xaxis min=0 max=2000 values=(0 to 2000 by 200);
   yaxis min=0 max=1 values=(0 to 1 by 0.1);
run;

Ready to join fellow brilliant minds for the SAS Hackathon?

Build your skills. Make connections. Enjoy creative freedom. Maybe change the world. Registration is now open through August 30th. Visit the SAS Hackathon homepage.

Register today!
Mastering the WHERE Clause in PROC SQL

SAS' Charu Shankar shares her PROC SQL expertise by showing you how to master the WHERE clause using real winter weather data.

Find more tutorials on the SAS Users YouTube channel.

Discussion stats
  • 10 replies
  • 3961 views
  • 7 likes
  • 4 in conversation