*! 1.0.0 NJC 12 Nov 2002
program define ciw, rclass byable(recall)
	version 6
	global S_1		/* # obs	*/
	global S_3		/* mean		*/
	global S_4		/* se of mean	*/
	global S_5		/* lower bound	*/
	global S_6		/* upper bound	*/

	syntax [varlist] [if] [in] [fw] [, Level(integer $S_level)  /*
	*/ BY(varlist) Total ]

	if "`by'"!="" {		/* backwards compatibility */
		if _by() {
			di in red /*
			*/ "by() option may not be combined with by prefix"
			exit 190
		}
		if "`weight'" != "" {
			local wgt `"[`weight'`exp']"'
		}
		if "`level'" != "" {
			local level "level(`level')"
		}
		by `by': ciw `varlist' `if' `in' `wgt', `level' `total'
		exit
	}

	if "`total'" != "" & !_by() {
		di in red "option total may only be specified with by"
		exit 198
	}

	tokenize `varlist'

	if `level'<10 | `level'>99 {
		di in red "level() invalid"
		exit 198
	}

	tempvar touse
	mark `touse' [`weight'`exp'] `if' `in'

	if _by() & _bylastcall() & "`total'"!="" {
				/* set alluse for later use */
		tempvar alluse
		mark `alluse' [`weight'`exp'] `if' `in', noby
	}

	local weight "[`weight'`exp']"
	tempvar BYGRP

	di
	Ci `varlist' `weight' if `touse', level(`level')
	ret add  /* add return values from Ci */

	if _by() & _bylastcall() & "`total'"!="" {
		di _n in gr _dup(79) "_" _n "-> Total"
		if "`level'"!="" {
			local level "level(`level')"
		}
		ciw `varlist' if `alluse' `weight', `level'
		return clear
		ret add
	}
end

/*
	In program Ci, we know the `if' is resolved to a touse variable
	and marks out everything except the missing values of the
	variables.  Therefore, we do not reduce it again but just use `if'
*/

program define Ci, rclass
	syntax varlist [fw] [if] [, Level(integer $S_level) ]

	tempvar tousex
	local ttl "    Mean"
	local tl1 "    Obs "
	di in smcl in gr _col(56) "{hline 3} Wilson Score {hline 3}"

	#delimit ;
	di in smcl in gr
"    Variable {c |} `tl1'    `ttl'    Std. Err.       [`level'% Conf. Interval]"
	_n "{hline 13}{c +}{hline 61}" ;
	#delimit cr
	global S_1 0
	global S_2 .
	global S_3 .
	global S_4 .
	global S_5 .
	global S_6 .

	tempname z A B C lb ub
	scalar `z' = invnorm((100 + `level') / 200)

	tokenize `varlist'
        while ("`1'"!="") {
		local toprt 1
		capture confirm string var `1'
		if _rc==0 {
			local toprt 0
		}
		else {
			capture assert `1'==0 | `1'==1 | `1'==. `if'
			if _rc {
				local toprt 0
			}
			else {
				sum `1' [`weight'`exp'] `if', meanonly
				local n = r(N)
				local k = r(sum)
				ret scalar N = `n'
				ret scalar mean = `k'/`n'
				ret scalar se=sqrt((return(mean)* /*
					*/ (1-return(mean)))/`n')
				scalar `A' = 2 * `k' + (`z')^2
				scalar `B' = /*
	*/ `z' * sqrt((`z')^2 + 4 * `n' * return(mean) * (1 - return(mean)))
				scalar `C' = 2 * (`n' + (`z')^2)
				scalar `lb' = (`A' - `B') / `C'
			       	scalar `ub' = (`A' + `B') / `C'
				ret scalar lb = `lb'
				ret scalar ub = `ub'
				/* double save in S_# and r() */
				global S_1 `return(N)'
				global S_3 `return(mean)'
				global S_4 `return(se)'
				global S_5 `return(lb)'
				global S_6 `return(ub)'
			}
			if `toprt' {
				local fmt : format `1'
				if substr("`fmt'",-1,1)=="f" {
					local ofmt="%9."+substr("`fmt'",-2,2)
				}
				else if substr("`fmt'",-2,2)=="fc" {
					local ofmt="%9."+substr("`fmt'",-3,3)
				}
				else	local ofmt "%9.0g"
				di in smcl in gr /*
				*/ %12s abbrev("`1'",12) " {c |}" _col(14) /*
				*/ in yel %8.0f return(N) /*
		 		*/ _col(27) `ofmt' return(mean) /*
		 		*/ _col(39) `ofmt' return(se) /*
		 		*/ _col(55) `ofmt' return(lb) /*
		 		*/ _col(67) `ofmt' return(ub) in gr "`mark'"
			}
		}
		mac shift
	}
end
exit