*! version 2.0.1 24feb2000 *! syntax [if] [in] [, Quant(integer 50) BY(varname) Level(integer $S_level) ] program define stquant, rclass version 6 st_is 2 analysis /* By option added */ syntax [if] [in] [, Quant(integer 50) BY(varname) Level(integer $S_level) ] tempvar touse st_smpl `touse' `"`if'"' `"`in'"' `"`by'"' `""' if `level'<10 | `level'>99 { di in red "level() invalid" exit 198 } if `quant'<5 | `quant'>94 { di in red "quant() invalid" exit 198 } /* DispHdr adapted from stsum */ DispHdr `level' `quant' `by' quietly { tempname fplus fminus sca `fplus' = (`quant' + 5)/100 sca `fminus' = (`quant' - 5)/100 local quant = `quant'/100 } if `"`by'"' != `""' { tempvar grp subuse sort `touse' `by' qui{ by `touse' `by': gen long `grp'=1 if _n==1 & `touse' replace `grp'=sum(`grp') if `touse' } local ng = `grp'[_N] local i 1 while `i' <= `ng' { qui gen byte `subuse'=`touse' & `grp'==`i' /* DoStats wraps old function */ DoStats `subuse' `level' `quant' `fplus' `fminus' `"`by'"' drop `subuse' local i = `i' + 1 } di in gr _dup(9) `"-"' `"+"' _dup(69) `"-"' } DoStats `touse' `level' `quant' `fplus' `fminus' `""' if $ties > 0 { di _n in bl _col(1) "Brookmeyer-Crowley limits could be inaccurate" /* */ " in presence of tied survival" _n "times." } ret add end program define DispHdr /* by */ args level quant ttl1 di _n in gr _col(10) `"| no. of"' _col(20) " no. of" /* */ _col(30) " `quant'" _col(39) /* */ `"|-------- `level'% Confidence limits --------|"' di in gr `"`ttl1'"' _col(10) `"| events"' _col(22) `"ties"' /* */ _col(28) "percentile" _col(40) "Large Sample Appr. " /* */ " Brookmeyer-Crowley" _n /* */ _dup(9) `"-"' `"+"' _dup(69) `"-"' end program define DoStats, rclass args touse level quant fplus fminus by local d : char _dta[st_d] local t : char _dta[st_t] preserve qui { keep if `touse' count if `d'==1 } local N_deads = r(N) st_ct "" -> t pop die gen die_cum=sum((die>1)*die) local N_ties=die_cum[_N] global ties `N_ties' restore, preserve qui keep if `touse' /* Estimate Large Sample Approximation */ tempname s gren lb ub median Var_med t_u t_l /* */ up lo s_u s_l br_up br_lo capture { * sts gen `s'=s /* bisogna rivedere per i casi estremi con stcox,estimate */ stcox,estimate bases(`s') sts gen `gren'=se(s) sts gen `lb'=lb(s), l(`level') sts gen `ub'=ub(s), l(`level') } if _rc!=0 { local median . local lo . local up . local br_lo . local br_up . Settitle `touse' `"`by'"' local ttl `"$S_4"' Displine `"`ttl'"' `N_deads' `N_ties' `median' /* */ `lo' `up' `br_lo' `br_up' exit } sort `t' /* Findptl as well as Settitle and Displine are adapted from stsum */ Findptl `quant' `s' `gren' scalar `median' = $S_1 if `median'==. { local lo . local up . local br_lo . local br_up . Settitle `touse' `"`by'"' local ttl `"$S_4"' Displine `"`ttl'"' `N_deads' `N_ties' `median' /* */ `lo' `up' `br_lo' `br_up' exit } scalar `Var_med' = $S_2^2 Findptl2 `fplus' `s' scalar `t_u' = $S_1 scalar `s_u' = $S_2 Findptl `fminus' `s' scalar `t_l' = $S_1 scalar `s_l' = $S_3 tempname f_t Var_t up lo /* Hosmer & Lemeshow (2.12) */ sca `f_t'=(`s_u'-`s_l')/(`t_l'-`t_u') /* (2.13) */ sca `Var_t'=`Var_med'/`f_t'^2 local z = invnorm(1-(1-`level'/100)/2) /* (2.14) */ sca `up' = `median' + `z'*sqrt(`Var_t') sca `lo' = `median' - `z'*sqrt(`Var_t') sca `up' = round(`up',.0001) sca `lo' = round(`lo',.0001) /* Brookmeyer-Crowley limits are estimated according to p. 51 as t_min(percentile,1] and not according to p. 154 as t_min[percentile,1]. 154 */ Findptl2 `quant' `ub' scalar `br_up' = $S_1 Findptl `quant' `lb' scalar `br_lo' = $S_1 /* saving results */ ret scalar Med = `median' ret scalar L_up = `up' ret scalar L_lo = `lo' ret scalar BC_up = `br_up' ret scalar BC_lo = `br_lo' ret scalar f_t50 = `f_t' ret scalar Var_t50 = `Var_t' Settitle `touse' `"`by'"' local ttl `"$S_4"' Displine `"`ttl'"' `N_deads' `N_ties' `median' `lo' `up' `br_lo' `br_up' end program define Findptl /* percentile s greenwood-s.e.*/ args p s gren tempvar j /* j0 is useless if `touse' keeped */ quietly { gen long `j' = _n if `s'<=`p' summ `j' local j=r(min) } global S_1 = _t[`j'] global S_2 = `gren'[`j'] global S_3 = `s'[`j'] end program define Findptl2 /* percentile s */ args p s tempvar j quietly { gen long `j' = _n if `s' >= `p' summ `j' local j=r(max) } global S_1 = _t[`j'] global S_2 = `s'[`j'] end program define Settitle /* touse byvars */ args touse byvars if `"`byvars'"'==`""' { global S_4 `"total"' exit } quietly { tempvar j gen long `j' = _n if `touse' summ `j' local j = r(min) } mac shift local ty : type `1' if substr(`"`ty'"',1,3)==`"str"' { local v = trim(substr(trim(`1'[`j']),1,8)) } else { local v = `1'[`j'] local v : label (`1') `v' 8 } global S_4 `"`v'"' end program define Displine args ttl N_deads N_ties median lo up br_lo br_up local ttl = trim(`"`ttl'"') local skip = 8-length(`"`ttl'"') di in gr _skip(`skip') `"`ttl' | "' in ye /* */ %6.0f `N_deads' `" "' %6.0f `N_ties' /* */ _col(24) %9.0g `median' `" "' /* */ %9.0g `lo' `" "' %9.0g `up' `" "' /* */ %8.0g `br_lo' `" "' %8.0g `br_up' end exit stquant, by(hercoc) | no. of no. of 50 |-------- 95% Confidence limits --------| hercoc | events ties percentile Large Sample Appr. Brookmeyer-Crowley ---------+--------------------------------------------------------------------- 1 | 92 20 150 102.3492 197.6508 106 190 2 | 100 25 151 110.0249 191.9751 110 177 3 | 136 46 186 143.8734 228.1266 147 224 4 | 165 50 181 150.7872 211.2128 153 211 ---------+--------------------------------------------------------------------- total | 493 349 168 149.6521 186.3479 153 184 Brookmeyer-Crowley limits could be inaccurate in presence of tied survival times.