*! v 1.0.0 PR/WvP 24may2013 /* Simplified version of WvP ira.ado, last updated 26/10/2012. Temporary variables: PART to define the current partition in merged sets. VIOL to detect a violation of the required ordering and the need for an additional merge. M mean of response variable. */ program define irax, sortpreserve quietly { version 11.0 syntax varlist(min=2 max=2 numeric) [if] [in] /// [, COMbine GENerate(string) noPTs REVerse ci noGRaph *] if "`generate'" != "" { gettoken generate rest : generate, parse(" ,") tokenize `"`rest'"', parse(" ,") while "`1'" != "" { if "`1'" == "replace" { local gen_replace replace continue, break } mac shift } } marksample touse gettoken y xvar : varlist sum `y' if `touse', meanonly if r(min) == r(max) { di as err "`y' does not vary" exit 198 } local mean_y = r(mean) count if (`touse'==1) & !inlist(`y', 0, 1) if (r(N)==0) local type LR // Logistic regression else local type LINR // Linear regression noi di _n as txt "type = `type'" tempvar PART VIOL HR M x if "`reverse'"=="" { gen `x' = -`xvar' if `touse' } else gen `x' = `xvar' if `touse' gen int `PART' = 1 if `touse'==1 sort `PART' `x' `y' replace `PART' = `PART'[_n-1] + (`x' > `x'[_n-1]) if !missing(`PART') & _n > 1 if "`reverse'"=="" { replace `x' = -`x' } sort `PART' by `PART': gen `M' = sum(`y') if !missing(`PART') by `PART': replace `M' = `M'[_N] / _N gen int `VIOL' = sum((`M' >= `M'[_n-1]) & (`PART'>`PART'[_n-1]) & !missing(`PART')) while `VIOL'[_N] != 0 { replace `PART' = `PART'[_n-1] + (`M' < `M'[_n-1]) if !missing(`PART') & _n > 1 sort `PART' by `PART': replace `M' = sum(`y') if !missing(`PART') by `PART': replace `M' = `M'[_N] / _N replace `VIOL' = sum((`M' >= `M'[_n-1]) & (`PART' > `PART'[_n-1]) & !missing(`PART')) } if ("`type'"=="LR") label variable `M' "Event probability" else if ("`type'"=="LINR") label variable `M' "Mean of `y'" if "`combine'" != "" { // For the -combine- option, need to create the "other" curve if ("`reverse'" == "") local Reverse reverse tempvar tempfit irax `y' `xvar' if `touse', `Reverse' nograph generate(`tempfit', replace) replace `M' = `M' + `tempfit' - `mean_y' drop `tempfit' `tempfit'_p // Update partition to one based on the new mean-y groups drop `PART' egen int `PART' = group(`M') if `touse' /* // Not clear if we should best re-estimate mean for new partition. Can easily be done: drop `M' sort `PART' by `PART': gen `M' = sum(`y') if !missing(`PART') by `PART': replace `M' = `M'[_N] / _N */ } if "`ci'" != "" { // Crude pointwise CI from partition model tempvar se lci uci tempname z scalar `z' = invnormal((100 + c(level))/200) if "`type'"=="LR" { local cmd logit local backtransf invlogit local transf logit } else { local cmd regress } `cmd' `y' ibn.`PART' if `touse' predict `se' if `touse', stdp gen `lci' = `backtransf'(`transf'(`M') - `z' * `se') gen `uci' = `backtransf'(`transf'(`M') + `z' * `se') drop `se' } /* Create graph. */ if "`graph'" != "nograph" { local title Isotonic Regression Analysis if ("`combine'" != "") local title `title' (extended) if "`type'" == "LINR" { local varlab: var lab `y' if ("`varlab'"=="" | index("`varlab'", ")") > 0) local varlab `y' local yplot = cond("`pts'" == "nopts", "", "`y'") if "`ci'" == "" { scatter `M' `yplot' `xvar' if `touse', sort connect(J .) msymbol(i oh) /// title(`title') ytitle("`varlab'") `options' } else { scatter `M' `lci' `uci' `yplot' `xvar' if `touse', sort connect(J J J .) lpattern(l shortdash ..) /// cmissing(y n n) msymbol(i i i oh) title(`title') ytitle("`varlab'") legend(off) `options' } } else { if "`ci'" == "" { line `M' `xvar' if `touse', sort connect(J) title(`title') `options' } else { line `M' `lci' `uci' `xvar' if `touse', sort connect(J J J) lpattern(l shortdash ..) /// cmissing(y n n) title(`title') legend(off) `options' } } } if "`generate'" != "" { local lab : var lab `M' compute `generate' = `M', `gen_replace' label("`lab'") noi di as txt "[variable `generate' created]" compute `generate'_p = `PART', `gen_replace' label("partition of `xvar'") noi di as txt "[variable `generate'_p created]" if "`ci'" != "" { compute `generate'_lci = `lci', `gen_replace' label("lower CL for `lab'") compute `generate'_uci = `uci', `gen_replace' label("upper CL for `lab'") noi di as txt "[variables `generate'_lci and `generate'_uci created]" } } } end * v 1.0.1 PR 03mar2013 program define compute version 8.0 gettoken type 0 : 0, parse("= ") bind // Process putative type local ok 0 foreach t in byte int long float double { if "`t'" == "`type'" { local ok 1 continue, break } } if !`ok' { if substr("`type'", 1, 3) == "str" { local strn = substr("`type'", 4, .) confirm integer number `strn' local ok 1 } } if !`ok' { local newvar `type' local type } else gettoken newvar 0 : 0, parse("= ") bind gettoken eqs 0 : 0, parse("= ") if "`eqs'" != "=" { di "{p}{err}syntax is {cmd:compute [{it:type}] {it:existing_var}|{it:newvar} = {it:exp}}" /// " [, {cmd:replace} {cmd:force} {cmd:label(}{it:label}{cmd:)}]{p_end}" exit 198 } gettoken Exp 0 : 0, parse(", ") bind syntax [if] [in] [, replace LABel(string) force ] if "`type'" != "" { local ok 0 foreach t in byte int long float double { if "`t'" == "`type'" { local ok 1 continue, break } } if !`ok' { if substr("`type'", 1, 3) == "str" { local strn = substr("`type'", 4, .) confirm integer number `strn' local ok 1 } } if !`ok' { di as err "type `type' not recognized" exit 198 } } capture confirm var `newvar', exact local rc = c(rc) if `rc' != 0 { // `newvar' does not exist; safe to create it from `Exp' generate `type' `newvar' = `Exp' `if' `in' } else { // `newvar' exists if "`replace'" != "" { // safe to recreate `newvar' replace `newvar' = `Exp' `if' `in' if "`type'" != "" { recast `type' `newvar', `force' } } else { di as err "`newvar' already defined" exit 110 } } if "`label'" != "" { label var `newvar' "`label'" } end