Proc Lifetest 2- Confidence Interval

SAS Day 29 Proc Lifetest – Confidence Interval


Last time we went over the Kaplan Meier Plot. Today, we will go over a sample program to generate the x% Confidence Interval in Proc Lifetest.

silviarita / Pixabay


Sample Output:


94.7% subjects have a duration of Response >= 12 months. 95% of the time the true interval lies in between 80.6% and 98.7%.

Sample SAS Code:

ods listing close;
ods output productlimitestimates=km quartiles=quartile censoredsummary=eventdsn;
proc lifetest data=adovsur2 method=km timelist=0 to 12 by 6  outsurv=surv;  
  strata treat/test=(logrank);
  time aval*cnsr(1);

data surv1;
  set surv;
  if _censor_=0;
  *added for empty sdf_lcl;
  if survival=0 then survival=1;
  if sdf_lcl=. then sdf_lcl=1;
  if sdf_ucl=. then sdf_ucl=1;
  proc sort; by treat aval survival;

proc sort data=km; by treat aval survival;

data km1;
  merge km(in=a) surv1(in=b);
  by treat aval survival;
  if a and b;
  length subgrp $50;
  subgrp=put(survival*100,4.1)||'% ('||put(sdf_lcl*100,4.1)||', '|| put(sdf_ucl*100,4.1)||')';
  proc sort; by timelist treat;

proc transpose data=km1 out=km2(drop=_name_ _label_) prefix=_;
  var subgrp;
  by  timelist;
  id  treat;
data km2(keep = label subgrp); 
  length label $100; 
  set km2; 
  label='  '||'% of Subjects with Duration of Response >= '||strip(put(timelist,2.))||' months (95% CI)';
  rename _1 = subgrp ;


Quartile CI Sample Output:


Sample SAS Code:

data quartile1;
  set quartile;
  length rngl rngh $5 median $5 ci $50; 
  if percent=50;
  if estimate>. then median=put(estimate,5.1);
  if lowerlimit>. then rngl=put(lowerlimit,5.1);
  if upperlimit>. then rngh=put(upperlimit,5.1);
  ci='('||rngl||', '||rngh||')';

proc transpose data=quartile1 out=quartile2 prefix=_;
  var median ci;
  id treat;
data quartile2; length label $100; 
set quartile2; iorder=2; ord=_n_; 
if lowcase(_name_)='median' then label='Median Duration of Response (months)'; 
else label='95% CI for Median Duration of Response'; run; *Confidence Interval;

data eventdsn1;
  set eventdsn;
  if missing(control_var);
  length dth csn $50;
  *dth=put(failed,5.)||' ('||put(round(d_pct,.1),5.1)||'%)';
  *csn=put(censored,5.)||' ('||put(round(c_pct,.1),5.1)||'%)';
   dth=put(failed,5.)||' ('||put(100-round(pctcens,.1),5.1)||'%)';
   csn=put(censored,5.)||' ('||put(round(pctcens,.1),5.1)||'%)';

proc transpose data=eventdsn1 out=eventdsn2 prefix=_;
  var dth csn;
  id treat;
data eventdsn2; length label $100; set eventdsn2;
iorder=1; ord=_n_; if lowcase(_name_)='dth' then label='  Duration of Response Observed - n (%)'; 
else label='  Duration of Response Censored - n (%)'; run;  *Death or Progression;

data dummy; length label $100; iorder=1; ord=0; label='Duration of Response'; run;

data all_dur;  
  set dummy eventdsn2 quartile2 ;
   rename _1 = subgrp;


Since we used a dummy dataset, the output does not make much sense from a statistical point of view. In general, we would like to generate the Median of Response, 95% CI for Median Response, Censored Objects, and Death Objects for all the efficacy related tables. Such as PFS (progression-free survival), Responder (Complete Response, Unconfirmed-complete Response, Partial Response), OS(overall survival) tables.
Note:  we need to use 100- percent for some cases. 

After all, there are many ways to derive the Confidence interval from ADSL and ADTTE dataset. We can always try a new approach!

Happy SAS Practicing!  🤟

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Social media & sharing icons powered by UltimatelySocial
%d bloggers like this: