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:
Interpretation:
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); run; 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; run; 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; run; proc transpose data=km1 out=km2(drop=_name_ _label_) prefix=_; var subgrp; by timelist; id treat; run; data km2(keep = label subgrp); length label $100; set km2; iorder=3; ord=_n_; label=' '||'% of Subjects with Duration of Response >= '||strip(put(timelist,2.))||' months (95% CI)'; rename _1 = subgrp ; run;
Quartile CI Sample Output:
Sample SAS Code:
data quartile1; set quartile; length rngl rngh $5 median $5 ci $50; if percent=50; rngl='NA'; rngh='NA'; median='NA'; 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||')'; run; proc transpose data=quartile1 out=quartile2 prefix=_; var median ci; id treat; run; 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; c_pct=100*Censored/&pop1; d_pct=100*Failed/&pop1; *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)||'%)'; run; proc transpose data=eventdsn1 out=eventdsn2 prefix=_; var dth csn; id treat; run; 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 ; seq=1; rename _1 = subgrp; run;
Summary:
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!