*! 1.1.2 NJC 31 October 2024 * 1.1.1 NJC 26 October 2024 * 1.1.0 NJC 25 October 2024 * 1.0.0 NJC 21 October 2024 program cisets version 14.1 gettoken subcmd 0 : 0 if substr("`subcmd'", 1, 4) == "mean" { _mean `0' } else if substr("`subcmd'", 1, 4) == "prop" { _prop `0' } else if substr("`subcmd'", 1, 3) == "var" { _var `0' } else if "`subcmd'" == "gmean" { _gmean `0' } else if "`subcmd'" == "hmean" { _hmean `0' } else if "`subcmd'" == "centile" { _centile `0' } else { display as err "did not understand subcommand `subcmd'" exit 198 } end * I guess shorter code would be entirely possible with more programs, * but it might be harder to follow the flow. * In essence, once each statistic -whatever- is chosen the * default program _whatever loops over or more variables using * -postfile- to assemble a confidence interval set. * But if -over()- is specified, we branch off to program _whatever_g * which handles groups of observations using -statsby-. * Here we keep a record of which weights are allowed. * mean aweight (if normal), fweight * proportion fweight * variance / SD fweight * geometric mean aweight, fweight * harmonic mean aweight, fweight * centile none program _mean capture syntax varname(numeric) [if] [in] [aweight fweight] /// , OVER(varname) [ SAVING(str asis) Level(integer $S_level) Total /// POISson EXPosure(passthru) * ] if _rc == 0 { if "`weight'" == "aweight" & "`poisson'`exposure'" != "" { display as err "aweights not allowed for Poisson means" exit 101 } _mean_g `0' exit 0 } syntax varlist(numeric) [if] [in] [aweight fweight] /// [, SAVING(str asis) Level(integer $S_level) /// POISson EXPosure(passthru) ALLobs inclusive cw * ] if "`weight'" == "aweight" & "`poisson'`exposure'" != "" { display as err "aweights not allowed for Poisson means" exit 101 } if "`allobs'`inclusive'`cw'" != "" marksample touse, novarlist else marksample touse quietly count if `touse' if r(N) == 0 error 2000 if r(N) == 1 error 2001 preserve quietly keep if `touse' if `"`saving'"' == "" { tempfile saving local wantsave 0 } else local wantsave 1 tempname handle postfile `handle' str32 varname str80 varlabel n point se lb ub using `saving' quietly foreach v of local varlist { local varlabel : var label `v' if `"`varlabel'"' == "" local varlabel "`v'" ci means `v', `poisson' `exposure' post `handle' ("`v'") ("`varlabel'") (r(N)) (r(mean)) (r(se)) (r(lb)) (r(ub)) } postclose `handle' gettoken filename rest : saving, parse(,) use "`filename'", clear gen level = `level' gen statname = "mean" if "`poisson'`exposure'" != "" { gen options = trim("`poisson' `exposure'") } if "`weight'" != "" gen weight = "`weight' `exp'" order varname varlabel n statname point se lb ub level list, noobs `options' if `wantsave' { display quietly compress save "`filename'", replace } end program _mean_g syntax varname(numeric) [if] [in] [aweight fweight] /// , OVER(varname) [ SAVING(str asis) Level(integer $S_level) Total /// POISson EXPosure(passthru) * ] marksample touse markout `touse' `over', strok quietly count if `touse' if r(N) == 0 error 2000 if r(N) == 1 error 2001 preserve quietly keep if `touse' local varlabel : variable label `varlist' local gvarlabel : variable label `over' quietly statsby , by(`over') clear `total' : /// ci means `varlist' [`weight' `exp'], `poisson' `exposure' level(`level') quietly egen group = group(`over'), label _crcslbl group `over' quietly if "`total'" != "" { su group, meanonly local gmax = r(max) + 1 replace group = `gmax' if group == . label def group `gmax' "Total", modify } rename (`over' N mean) (origgvar n point) gen varname = "`varlist'" gen varlabel = cond(missing("`varlabel'"), varname, "`varlabel'") gen groupvar = "`over'" gen gvarlabel = cond(missing("`gvarlabel'"), groupvar, "`gvarlabel'") gen statname = "mean" if "`poisson'`exposure'" != "" { gen options = trim("`poisson' `exposure'") } if "`weight'" != "" gen weight = "`weight' `exp'" foreach v in n point se ub lb level { label var `v' } order varname varlabel origgvar groupvar gvarlabel group n statname point se lb ub level list, noobs `options' if `"`saving'"' != "" { label data display quietly compress save `saving' } end program _prop capture syntax varname(numeric) [if] [in] [fweight] /// , OVER(varname) [ SAVING(str asis) Level(integer $S_level) Total /// exact wald wilson AGRESti JEFFreys * ] if _rc == 0 { _prop_g `0' exit 0 } syntax varlist(numeric) [if] [in] [fweight] /// [, SAVING(str asis) Level(integer $S_level) /// exact wald wilson AGRESti JEFFreys ALLobs inclusive cw * ] if "`allobs'`inclusive'`cw'" != "" marksample touse, novarlist else marksample touse quietly count if `touse' if r(N) == 0 error 2000 if r(N) == 1 error 2001 preserve quietly keep if `touse' if `"`saving'"' == "" { tempfile saving local wantsave 0 } else local wantsave 1 tempname handle postfile `handle' str32 varname str80 varlabel n point se lb ub using `saving' local bad = 0 local nv : word count `varlist' quietly foreach v of local varlist { count if !(inlist(`v', 0, 1) | missing(`v')) if r(N) { local flag `flag' `v' local ++bad continue } local varlabel : var label `v' if `"`varlabel'"' == "" local varlabel "`v'" ci prop `v', `exact' `wald' `wilson' `agresti' `jeffreys' post `handle' ("`v'") ("`varlabel'") (r(N)) (r(mean)) (r(se)) (r(lb)) (r(ub)) } postclose `handle' noisily if "`flag'" != "" { display _n "{p}" plural(`bad', "variable") " ignored: `flag'{p_end}" display "{p}(0, 1) binary variables are needed for confidence intervals for proportions{p_end}" if `bad' == `nv' exit 450 } gettoken filename rest : saving, parse(,) use "`filename'", clear gen level = `level' gen statname = "proportion" if "`exact'`wald'`wilson'`agresti'`jeffreys'" != "" { gen options = trim("`exact' `wald' `wilson' `agresti' `jeffreys'") } if "`weight'" != "" gen weight = "`weight' `exp'" order varname varlabel n statname point se lb ub level list, noobs `options' if `wantsave' { display quietly compress save "`filename'", replace } end program _prop_g syntax varname(numeric) [if] [in] [fweight] /// , OVER(varname) [ SAVING(str asis) Level(integer $S_level) Total /// exact wald wilson AGRESti JEFFreys * ] marksample touse markout `touse' `over', strok quietly count if `touse' if r(N) == 0 error 2000 if r(N) == 1 error 2001 preserve quietly keep if `touse' quietly count if !inlist(`varlist', 0, 1) if r(N) { noisily display _n "{p}(0, 1) binary variables are needed for confidence intervals for proportions{p_end}" exit 450 } local varlabel : variable label `varlist' local gvarlabel : variable label `over' quietly statsby , by(`over') clear `total' : /// ci prop `varlist' [`weight' `exp'], level(`level') `exact' `wald' `wilson' `agresti' `jeffreys' quietly egen group = group(`over'), label _crcslbl group `over' quietly if "`total'" != "" { su group, meanonly local gmax = r(max) + 1 replace group = `gmax' if group == . label def group `gmax' "Total", modify } rename (`over' N mean) (origgvar n point) drop proportion gen varname = "`varlist'" gen varlabel = cond(missing("`varlabel'"), varname, "`varlabel'") gen groupvar = "`over'" gen gvarlabel = cond(missing("`gvarlabel'"), groupvar, "`gvarlabel'") gen statname = "proportion" if "`exact'`wald'`wilson'`agresti'`jeffreys'" != "" { gen options = trim("`exact' `wald' `wilson' `agresti' `jeffreys'") } if "`weight'" != "" gen weight = "`weight' `exp'" foreach v in n point se ub lb level { label var `v' } order varname varlabel origgvar groupvar gvarlabel group n statname point se lb ub level list, noobs `options' if `"`saving'"' != "" { label data display quietly compress save `saving' } end program _var capture syntax varname(numeric) [if] [in] [fweight] /// , OVER(varname) [ SAVING(str asis) Level(integer $S_level) Total SD BONett * ] if _rc == 0 { _var_g `0' exit 0 } syntax varlist(numeric) [if] [in] [fweight] /// [, SAVING(str asis) Level(integer $S_level) SD BONett ALLobs inclusive cw * ] if "`allobs'`inclusive'`cw'" != "" marksample touse, novarlist else marksample touse quietly count if `touse' if r(N) == 0 error 2000 if r(N) == 1 error 2001 preserve quietly keep if `touse' if `"`saving'"' == "" { tempfile saving local wantsave 0 } else local wantsave 1 tempname handle postfile `handle' str32 varname str80 varlabel n point lb ub using `saving' local which = cond("`sd'" != "", "sd", "Var") quietly foreach v of local varlist { local varlabel : var label `v' if `"`varlabel'"' == "" local varlabel "`v'" ci var `v' [`weight' `exp'], level(`level') `sd'`bonett' post `handle' ("`v'") ("`varlabel'") (r(N)) (r(`which')) (r(lb)) (r(ub)) } postclose `handle' gettoken filename rest : saving, parse(,) use "`filename'", clear gen level = `level' gen statname = cond("`sd'" != "", "SD", "variance") if "`sd'`bonett'" != "" { gen options = trim("`sd' `bonett'") } if "`weight'" != "" gen weight = "`weight' `exp'" order varname varlabel n statname point lb ub level list, noobs `options' if `wantsave' { display quietly compress save "`filename'", replace } end program _var_g syntax varname(numeric) [if] [in] [fweight] /// , OVER(varname) [ SAVING(str asis) Level(integer $S_level) Total /// SD BONett * ] marksample touse markout `touse' `over', strok quietly count if `touse' if r(N) == 0 error 2000 if r(N) == 1 error 2001 preserve quietly keep if `touse' local varlabel : variable label `varlist' local gvarlabel : variable label `over' quietly statsby , by(`over') clear `total' : /// ci var `varlist' [`weight' `exp'], level(`level') `sd' `bonett' quietly egen group = group(`over'), label _crcslbl group `over' quietly if "`total'" != "" { su group, meanonly local gmax = r(max) + 1 replace group = `gmax' if group == . label def group `gmax' "Total", modify } local which = cond("`sd'" != "", "sd", "Var") if "`sd'" != "" drop Var drop Var_se rename (`over' N `which') (origgvar n point) gen varname = "`varlist'" gen varlabel = cond(missing("`varlabel'"), varname, "`varlabel'") gen groupvar = "`over'" gen gvarlabel = cond(missing("`gvarlabel'"), groupvar, "`gvarlabel'") gen statname = cond("`sd'" == "sd", "SD", "variance") if "`sd'`bonett'" != "" { gen options = trim("`sd' `bonett'") } if "`weight'" != "" gen weight = "`weight' `exp'" foreach v in n point ub lb level { label var `v' } order varname varlabel origgvar groupvar gvarlabel group n statname point lb ub level list, noobs `options' if `"`saving'"' != "" { label data display quietly compress save `saving' } end program _gmean capture syntax varname(numeric) [if] [in] [aweight fweight] /// , OVER(varname) [ SAVING(str asis) Level(integer $S_level) Total /// overasis * ] if _rc == 0 { _gmean_g `0' exit 0 } syntax varlist(numeric) [if] [in] [aweight fweight] /// [, SAVING(str asis) Level(integer $S_level) ALLobs inclusive cw * ] if "`allobs'`inclusive'`cw'" != "" marksample touse, novarlist else marksample touse quietly count if `touse' if r(N) == 0 error 2000 if r(N) == 1 error 2001 preserve quietly keep if `touse' if `"`saving'"' == "" { tempfile saving local wantsave 0 } else local wantsave 1 tempname handle postfile `handle' str32 varname str80 varlabel n point lb ub using `saving' quietly foreach v of local varlist { local varlabel : var label `v' if `"`varlabel'"' == "" local varlabel "`v'" ameans `v' [`weight' `exp'], level(`level') post `handle' ("`v'") ("`varlabel'") (r(N_pos)) (r(mean_g)) (r(lb_g)) (r(ub_g)) if r(N) > r(N_pos) local flag `flag' `v' } postclose `handle' if "`flag'" != "" { noisily display _n "{p}note: zero or negative values on `flag' ignored{p_end}" } gettoken filename rest : saving, parse(,) use "`filename'", clear gen level = `level' gen statname = "geometric mean" if "`weight'" != "" gen weight = "`weight' `exp'" order varname varlabel n statname point lb ub level list, noobs `options' if `wantsave' { display quietly compress save "`filename'", replace } end program _gmean_g syntax varname(numeric) [if] [in] [aweight fweight] /// , OVER(varname) [ SAVING(str asis) Level(integer $S_level) Total * ] marksample touse markout `touse' `over', strok quietly count if `touse' if r(N) == 0 error 2000 if r(N) == 1 error 2001 preserve quietly keep if `touse' qui count if `varlist' <= 0 if r(N) { noisily display "`r(N)' values of `varlist' zero or negative; will be ignored" } local varlabel : variable label `varlist' local gvarlabel : variable label `over' quietly statsby , by(`over') clear `total' : /// ameans `varlist' [`weight' `exp'], level(`level') drop N mean lb ub *_h Var* quietly egen group = group(`over'), label _crcslbl group `over' quietly if "`total'" != "" { su group, meanonly local gmax = r(max) + 1 replace group = `gmax' if group == . label def group `gmax' "Total", modify } rename (`over' N_pos mean_g lb_g ub_g) (origgvar n point lb ub) gen varname = "`varlist'" gen varlabel = cond(missing("`varlabel'"), varname, "`varlabel'") gen groupvar = "`over'" gen gvarlabel = cond(missing("`gvarlabel'"), groupvar, "`gvarlabel'") gen statname = "geometric mean" if "`weight'" != "" gen weight = "`weight' `exp'" foreach v in n point ub lb level { label var `v' } order varname varlabel origgvar groupvar gvarlabel group n statname point lb ub level list, noobs `options' if `"`saving'"' != "" { label data display quietly compress save `saving' } end program _hmean capture syntax varname(numeric) [if] [in] [aweight fweight] /// , OVER(varname) [ SAVING(str asis) Level(integer $S_level) Total * ] if _rc == 0 { _hmean_g `0' exit 0 } syntax varlist(numeric) [if] [in] [aweight fweight] /// [, SAVING(str asis) Level(integer $S_level) ALLobs inclusive cw * ] if "`allobs'`inclusive'`cw'" != "" marksample touse, novarlist else marksample touse quietly count if `touse' if r(N) == 0 error 2000 if r(N) == 1 error 2001 preserve quietly keep if `touse' if `"`saving'"' == "" { tempfile saving local wantsave 0 } else local wantsave 1 tempname handle postfile `handle' str32 varname str80 varlabel n point lb ub using `saving' quietly foreach v of local varlist { local varlabel : var label `v' if `"`varlabel'"' == "" local varlabel "`v'" ameans `v' [`weight' `exp'], level(`level') post `handle' ("`v'") ("`varlabel'") (r(N_pos)) (r(mean_h)) (r(lb_h)) (r(ub_h)) if r(N) > r(N_pos) local flag `flag' `v' } postclose `handle' if "`flag'" != "" { noisily display _n "{p}note: zero or negative values on `flag' ignored{p_end}" } gettoken filename rest : saving, parse(,) use "`filename'", clear gen level = `level' gen statname = "harmonic mean" if "`weight'" != "" gen weight = "`weight' `exp'" order varname varlabel n statname point lb ub level list, noobs `options' if `wantsave' { display quietly compress save "`filename'", replace } end program _hmean_g syntax varname(numeric) [if] [in] [aweight fweight] /// , OVER(varname) [ SAVING(str asis) Level(integer $S_level) Total * ] marksample touse markout `touse' `over', strok quietly count if `touse' if r(N) == 0 error 2000 if r(N) == 1 error 2001 preserve quietly keep if `touse' qui count if `varlist' <= 0 if r(N) { noisily display "`r(N)' values of `varlist' zero or negative; will be ignored" } local varlabel : variable label `varlist' local gvarlabel : variable label `over' quietly statsby , by(`over') clear `total' : /// ameans `varlist' [`weight' `exp'], level(`level') drop N mean lb ub *_g Var* quietly egen group = group(`over'), label _crcslbl group `over' quietly if "`total'" != "" { su group, meanonly local gmax = r(max) + 1 replace group = `gmax' if group == . label def group' `gmax' "Total", modify } rename (`over' N_pos mean_h lb_h ub_h) (origgvar n point lb ub) gen varname = "`varlist'" gen varlabel = cond(missing("`varlabel'"), varname, "`varlabel'") gen groupvar = "`over'" gen gvarlabel = cond(missing("`gvarlabel'"), groupvar, "`gvarlabel'") gen statname = "harmonic mean" if "`weight'" != "" gen weight = "`weight' `exp'" foreach v in n point ub lb level { label var `v' } order varname varlabel origgvar groupvar gvarlabel group n statname point lb ub level list, noobs `options' if `"`saving'"' != "" { label data display quietly compress save `saving' } end program _centile capture syntax varname(numeric) [if] [in] /// , OVER(varname) [ SAVING(str asis) Level(integer $S_level) Total /// Centile(numlist max=1 >0 <100) CCi Normal Meansd * ] if _rc == 0 { _centile_g `0' exit 0 } syntax varlist(numeric) [if] [in] /// [ , SAVING(str asis) Level(integer $S_level) /// Centile(numlist max=1 >0 <100) CCi Normal Meansd ALLobs inclusive cw * ] if "`allobs'`inclusive'`cw'" != "" marksample touse, novarlist else marksample touse quietly count if `touse' if r(N) == 0 error 2000 if r(N) == 1 error 2001 preserve quietly keep if `touse' if `"`saving'"' == "" { tempfile saving local wantsave 0 } else local wantsave 1 tempname handle postfile `handle' str32 varname str80 varlabel n point lb ub using `saving' if "`centile'" == "" local centile 50 quietly foreach v of local varlist { local varlabel : var label `v' if `"`varlabel'"' == "" local varlabel "`v'" centile `v', centile(`centile') level(`level') `cci' `normal' `meansd' post `handle' ("`v'") ("`varlabel'") (r(N)) (r(c_1)) (r(lb_1)) (r(ub_1)) } postclose `handle' gettoken filename rest : saving, parse(,) use "`filename'", clear gen level = `level' gen statname = "`centile' pctile" if "`cci'`normal'`meansd'" != "" { gen options = trim("`cci' `normal' `meansd'") } order varname varlabel n statname point lb ub level list, noobs `options' if `wantsave' { display quietly compress save "`filename'", replace } end program _centile_g syntax varname(numeric) [if] [in] /// , OVER(varname) [ SAVING(str asis) Level(integer $S_level) Total /// Centile(numlist max=1 >0 <100) CCi Normal Meansd * ] marksample touse markout `touse' `over', strok quietly count if `touse' if r(N) == 0 error 2000 if r(N) == 1 error 2001 preserve quietly keep if `touse' local varlabel : variable label `varlist' local gvarlabel : variable label `over' if "`centile'" == "" local centile 50 quietly statsby , by(`over') clear `total' : /// centile `varlist', centile(`centile') level(`level') /// `cci' `normal' `meansd' quietly egen group = group(`over'), label _crcslbl group `over' quietly if "`total'" != "" { su group, meanonly local gmax = r(max) + 1 replace group = `gmax' if group == . label def group `gmax' "Total", modify } drop n_cent rename (`over' N c_1 lb_1 ub_1) (origgvar n point lb ub) gen varname = "`varlist'" gen varlabel = cond(missing("`varlabel'"), varname, "`varlabel'") gen groupvar = "`over'" gen gvarlabel = cond(missing("`gvarlabel'"), groupvar, "`gvarlabel'") gen statname = "`centile' pctile" gen level = `level' if "`cci'`normal'`meansd'" != "" { gen options = trim("`cci' `normal' `meansd'") } foreach v in n point ub lb level { label var `v' } order varname varlabel origgvar groupvar gvarlabel group n statname point lb ub level list, noobs `options' if `"`saving'"' != "" { label data display quietly compress save `saving' } end