*! phscore *! version 1.0.0 William H. Rogers (STB-19: ssa4) program define phscore version 3.1 if "$S_E_cmd"!="cox" { error 301 } local varlist "req ex" local if "opt" local in "opt" local options "CScore(string) UScore(string) DEad(string)" parse "`*'" parse "`varlist'", parse(" ") local nv : word count `*' local nn : word count `cscore' assert `nn' == `nv' tempvar obs gen long `obs' = _n sort `obs' cap drop _merge preserve if "`uscore'"=="" { tempvar uscore } quietly { if "`if'`in'"!="" { keep `if' `in' local if local in } if "`dead'"=="" { tempvar dead gen byte `dead' = 1 } keep if $S_E_depv!=. & `dead'!=. /* to do time-varying we would need to trace linkages */ tempvar ebx mtime denom sdenom predict `ebx' drop if `ebx'==. gen `mtime' = -$S_E_depv sort `mtime' `dead' gen `denom' = sum(`ebx') by `mtime': replace `denom' = `denom'[_N] * deriv of n/s is dn/s - n/s^2 ds ; dn==ebx xi, ds = sum(ebx xj) local i 1 while `i'<=`nv' { local nvar : word `i' of `cscore' gen `nvar' = `ebx'*``i'' gen `sdenom' = sum(`nvar') by `mtime': replace `sdenom' = `sdenom'[_N] replace `nvar' = ``i'' - `sdenom'/`denom' replace `nvar' = . if `dead'==0 local i = `i' + 1 drop `sdenom' } tempvar term aterm junk * want sum (1/denom) for all deaths with this obs in risk set gen `aterm' = `dead'/`denom' gen `junk' = sum(`aterm'[_N-_n+1]) drop `aterm' gen `term' = `junk'[_N-_n+1] drop `junk' by `mtime': replace `term' = `term'[1] gen `uscore' = `dead'-`ebx'*`term' sort `obs' keep `obs' `cscore' `uscore' tempfile SCORES save `SCORES' restore merge `obs' using `SCORES' drop _merge } end