*!********** Adjusted Chi2 Program ********
*! Estimates chi2 statistic for dichotomous outcomes
*! on clustered data. May 30, 2000. Jeph Herrin
*! see also clprob.ado, cldiff.ado, and clttest.ado

*
*  	Revised 14 Sep 2021 - check nesting of clusters
*
*

capture program drop clchi2
program define clchi2, rclass
	version 7.0
	syntax varlist(min=2 max=2 default=none) [if] [in] , /*
*/		CLuster(varname) [TABle] [STRata(varname)]
	marksample touse
	if "`cluster'"!="" {
		unabbrev `cluster', max(1)
		local clust "$S_1"
	}
	else {
		di in r "Must specify cluster"
		exit
	}

	if "`strata'"!="" {
		unabbrev `strata', max(1)
		local strata "$S_1"
	}
	tokenize `varlist', parse(" ")
	local var1 "`1'"
	local var2 "`2'"


	if "`cluster'"==""|"`var1'"==""|"`var2'"==""  {
		di in gr "Syntax for " in wh "clchi2" _c
		di in gr ", the clustered chi2 is:"
		di in wh "clchi2 " in gr "v1 v2 " in wh ", cluster(" _c
		di in gr "v3" in wh ") strata(" _c
		di in gr "v4" in wh ") [table] "
		di in gr "  where " in wh "v1 "
    	di in gr "is the dichotomous event variable"
		di in wh "        v2 " in gr "is the classification variable"
		di in wh "        v3 " in gr "is a required cluster variable"
		di in wh "        v4 " in gr "is an optional strata variable"
		exit
	}



	quietly {
	tempvar myin
	tempname CT CA CR chi2 obs df PT PA PR rholb rhoub
	tempname rho Nij Nt Xij P Pt summand nvar1 nvar2 nstr
	tempname M1 M2 A1 A2 chiMHA PM
	tempname C1 C2 rhowarn rhoa rhou rhoal rhoau ind
	tempvar summand CA PA N P R C E T O Nij Nt Pt strvar strstr
	tempvar topsum msum Mi Ai Ci size tmpvar

	gen byte `myin'= 1
	if ("`if'`in'"!="") {
		replace `myin'=0
		replace `myin'=1 `if' `in'
		}

	* check nesting
	tempvar evar
	bys `myin' `cluster' (`var2') : gen `evar'=`var2'[_N]!=`var2'[1]
	qui sum `evar' if `myin'
	if r(max)>0 {
		di in r "Clusters must be nested within var2"
		exit
	}

	if "`strata'"!="" {
		inspect `strata'
		scalar `nstr'=r(N_unique)
		if `nstr'==. {
			di in r "Must have 1-99 `strata'!"
			exit
		}
		capture confirm string variable `strata'
		if _rc== 0 {
			gen str20 `strstr'=`strata'
		}
		else {
			gen str20 `strstr'=string(`strata')
		}
		encode `strstr', gen(`strvar')
	}
	else {
		gen `strvar'=1
	}
	replace `myin'=`myin'&`var1'!=.&`var2'!=.&`clust'!=.&`strvar'!=.
	} /* end quietly */

	quietly {
		preserve
		************* Pearson's and Rho *******
		keep if `myin'
		count
		if r(N) ==0 {
			di in r "No observations"
			exit
		}
		quietly tab `var1' `var2', chi2
		scalar `chi2'=r(chi2)
		scalar `obs'=r(N)
		quietly inspect `var1'
		scalar `nvar1'=r(N_unique)
		quietly inspect `var2'
		scalar `nvar2'=r(N_unique)
		loneway `var1' `clust'
		capture confirm existence r(rho)
		if _rc!=0 {
			global S_1 0
			local warn "Estimated < 0"
		}
		scalar `rho'=r(rho)
*		di in r `rho'
		scalar `rholb'=r(lb)
		scalar `rhoub'=r(ub)
		if `rho'==. {
			di in red "`var1' not grouped within `clust'"
			exit
		}
		scalar `df' = (`nvar1'-1)*(`nvar2'-1)
		*****************************************
		restore
		preserve
		**********  Pooled-adjustment ***********
		keep if `myin'
		collapse (count) `Nij'=`var1', by(`clust')
		gen `summand'=((`Nij'-1)*`rho'+1)*`Nij'
		collapse (sum) `Nij' `summand'
		scalar `CT'=`summand'[1]/`Nij'[1]
		scalar `CT'=`chi2'/`CT'
		scalar `PT' = chiprob(`df',`CT')
		*******************************************
		restore
		preserve
		************ Group-adjustment**************
		keep if `myin'
		sort `clust'
		by `clust'  :gen `summand'=((_N-1)*`rho'+1)
		egen `CA'=sum(`summand'), by(`var2')
		collapse (sum) `O'=`myin' (max) `CA', by(`var1' `var2')
		egen `R'=sum(`O'),by(`var1')
		egen `C'=sum(`O'),by(`var2')
		egen `T'=sum(`O')
		replace `CA'=`CA'/`C'
		gen `E' = (`R'*`C')/(`T')
		gen `summand'=((`O'-`E')^2)/(`CA'*`E')
		collapse (sum) `summand'
		scalar `CA' = `summand'
		if `CA' < 0 { scalar `CA' = 0 }
		scalar `PA' = chiprob(`df',`CA')
		*******************************************
		restore
		preserve
		**********Adjusted MHA if stratified*******
		keep if `myin'
		if "`strata'"!="" {
			if `nvar1'!=2|`nvar2'!=2 {
				di in r "`var1'  = " `nvar1'
				di in r "`var2'  = " `nvar2'
				di in r "must have 2x2 for stratified MHA"
				exit
			}
			* make var1,var2 into  0/1
			gen `tmpvar'=`var1'==`var1'[1]
			replace `var1'=`tmpvar'
			replace `tmpvar'=`var2'==`var2'[1]
			replace `var2'=`tmpvar'
			drop `tmpvar'
			scalar `ind' = 1
			scalar `rhoa' = 0
			while `ind'<=`nstr' {
				quietly loneway `var1' `clust' if `strvar'==`ind'
				capture confirm existence r(rho)
				if _rc!=0 {
					global S_1 0
				}
				scalar `rhoa'=`rhoa'+r(rho)
				scalar `ind' =`ind'+1
			}
			scalar `rhoa'=`rhoa'/`nstr'
			local rhowarn ""
			if `rhoa'==. {
				scalar `rhoa'=`rho'
				local rhowarn "Unadjusted rho used for stratified analysis"
			}

			#delimit ;
			collapse (max) `strvar' `var2'
				 (count) `msum'=`var1'
				 (sum) `Ai'=`var1', by(`clust');
			#delimit cr
			gen `topsum'=`msum'*(1+(`msum'-1)*`rhoa')
			collapse (sum) `Mi'=`msum' `Ai' `topsum' , by(`strvar' `var2')
			gen `Ci'=`topsum'/`Mi'
			gen `M1'=`Mi' if `var2'==0
			gen `M2'=`Mi' if `var2'==1
			gen `A1'=`Ai' if `var2'==0
			gen `A2'=`Ai' if `var2'==1
			gen `C1'=`Ci' if `var2'==0
			gen `C2'=`Ci' if `var2'==1
			collapse (max) `M1' `M2' `A1' `A2' `C1' `C2' , by(`strvar')
			gen `topsum'=`A1'*(`M2'-`A2')-`A2'*(`M1'-`A1')
			replace `topsum'=`topsum'/(`M1'*`C2'+`M2'*`C1')
			gen `msum'=`M1'*`M2'*(`A1'+`A2')*(`M1'+`M2'-`A1'-`A2')
			replace `msum'=`msum'/(`M1'*`C2'+`M2'*`C1'+1)
			replace `msum'=`msum'/((`M1'+`M2')^2)
			collapse (sum) `topsum' `msum'
			scalar `chiMHA'=abs(`topsum')-0.5
			scalar `chiMHA'=`chiMHA'^2
			scalar `chiMHA'=`chiMHA'/`msum'
			scalar `PM' = chiprob(`df',`chiMHA')
			***** end MHA ****************************
		}
		restore

		scalar `P' = chiprob(`df',`chi2')
	}  /* end quietly */
	if "`table'"!="" {
		tab `var1' `var2' if `myin', col row
	}
	di
	display in y " `var1'" in g " by " in y "`var2'" in g /*
*/                     ", clustered by " in y "`clust'"
	di in g  " ------------------------------------------------------"
	display in gr "  Inter-cluster correlation" _col(29) "= " /*
*/                     in y %16.4f `rho'
	display in g "      ICC 95% Asymptotic CI" _col(29) "= " /*
*/                     in g "     [" %6.4f in y `rholb' /*
*/                     in g "," %6.4f in y `rhoub' in g "]"
	if "`warn'"!="" {
		display in gr " `warn'"
	}
	display %1.0f in gr "         Pearson's Chi-2(" in y `df' in g ") = " _c
	display %9.4f in y `chi2' _c
	display %6.4f in gr _skip(4) " Pr = " in y %6.4f `P'
	display %1.0f in gr " Pooled adjustment Chi-2(" in y `df' in g ") = " _c
	display %9.4f in y `CT' _c
	display %6.4f in gr _skip(4) " Pr = " in y %6.4f `PT'
	display %1.0f in gr "  Group adjustment Chi-2(" in y `df' in g ") = " _c
	display %9.4f in y `CA' _c
	display %6.4f in gr _skip(4) " Pr = " in y %6.4f `PA'
	return scalar g_pval=`PA'
	if "`strata'"!="" {
		di in g  " ------------------------------------------------------"
		if "`rhowarn'"!="" {
			display in gr " `rhowarn'"
		}
		else {
			display in gr "        Strata-adjusted ICC" _col(29) "= " /*
*/                    		 in y %16.4f `rhoa'
		}
		display %1.0f in gr "    Stratified M-H Chi-2(" in y `df' in g ") = " _c
		display %9.4f in y `chiMHA' _c
		display %6.4f in gr _skip(4) " Pr = " in y %6.4f `PM'
		return scalar g_pval=`PM'
	}
end
**************end program clchi2 ********