*! Chi2 goodness of fit test; v.2.0 by Stas Kolenikov program define chi2fit, rclass version 6.0 syntax varlist (numeric min=2 max=2) [if] [in] [fw pw/], [BINS(int 0) Detail DF(int 0)] * the syntax is: the first variable is the actual data, * the second variable is the cdf of the hypothetical data tokenize `varlist' local actual `1' local hypoth `2' marksample touse qui { * tempvar hypoth * g double `hypoth' = `exp' if `touse' tempvar counts if "`weight'"~="" { g `counts'=`exp' if `touse' sum `counts' if `touse' replace `counts' = `counts'*r(N)/r(sum) } else { g byte `counts' = 1 if `touse' } qui sum `counts' if `touse' local total = r(sum) * total number of observations used if `total'<32 { di in red "Are you sure you want to run this program with so few observations?" exit 8 } if `bins'==0 { local bins=int(log(`total')/log(2)+1) } if `bins'<=`df'+3 { local bins=`df'+3 } if "`detail'"~="" { noi di in gre _n "Using " in yel %3.0f `bins' in gre " bins for grouping" _n noi di in gre " Bins | From | To | Under H0 | Actual" noi di in gre "-------+--------+--------+----------+----------" } local sorted : sortedby if "`sorted'"=="" { tempvar tosort g long `tosort'=_n local sorted `tosort' } sort `touse' `hypoth' cap assert `actual' <= `actual'[_n+1] if `touse' if _rc==9 { di in red "Are you sure `exp' is a good enough cdf for `actual' ?" exit 9 } tempvar binno lower upper Nact Nhyp chi2 g byte `binno'=int(`hypoth'*`bins'+1) if `touse' local i=1 g double `lower'=. g double `upper'=. g long `Nact'=. g long `Nhyp'=. while `i'<=`bins' { if `i'==1 { replace `lower'=0 in `i' local lbndry "-infty" } else { replace `lower'=`upper'[_n-1] in `i' local lbndry `rbndry' } if `i'==`bins' { replace `upper'=1 in `i' local rbndry="+infty" } else { sum `hypoth' if `binno'==`i', meanonly local left=r(max) sum `hypoth' if `binno'==`i'+1, meanonly local right=r(min) replace `upper'=.5*(`right'+`left') in `i' sum `actual' if `binno'==`i', meanonly local left=r(max) sum `actual' if `binno'==`i'+1, meanonly local right=r(min) local rbndry=string(.5*(`right'+`left'),"%8.3f") } sum `counts' if `binno'==`i' cap assert r(N)>5 if _rc==9 { /* we should rebin our stuff */ } replace `Nact'=r(sum) in `i' replace `Nhyp'=(`upper'-`lower')*`total' in `i' if "`detail'"~="" { #delimit ; noi di _col(5) %-3.0f in yel `i' in gre _col(8) "| " in yel "`lbndry'" _col(17) in gre "| " in yel "`rbndry'" _col(26) in gre "| " in yel %7.2f `Nhyp'[`i'] in gre _col(37) "| " in yel %5.0g `Nact'[`i'] ; #delimit cr } local i=`i'+1 } /* end of while bin */ g double `chi2'=(`Nact'-`Nhyp')^2/`Nhyp' in 1/`bins' sum `chi2', meanonly return scalar df = `bins'-1-`df' return scalar chi2 = r(sum) return scalar pvalue = chiprob(return(df),return(chi2)) sort `sorted' } /* end of quietly */ if "`detail'"~="" { di in gre "-------+--------+--------+----------+----------" } #delimit ; di in gre _n " Goodness of fit chi-square test:" _n " comparing `actual' with `exp'" _n(2) _col(18) "Chi2 (" in yel %4.0f return(df) in gre ") = " in yel %-9.3f return(chi2) _n in gre _col(18) "Prob > Chi2 = " in yel %6.4f return(pvalue) ; #delimit cr end /* History: 1.2 ??? 2.0 syntax changed, [pw] added */