*! version 1.0.0 15dec2009 E. Leuven, B. Sianesi
program define pstest2
version 10.0
syntax varlist(min=1) [, Treated(varname) SUPport(varname) MWeight(varname) SUMmary QUIetly GRaph]

	capture confirm var _treated
	if _rc & "`treated'"=="" {
		di as error "Error: provide treatment indicator variable"
		exit 198
	}
	else if !_rc & "`treated'"=="" {
		tempvar treated
		qui g double `treated' = _treated
	}


	capture confirm var _weight
	if _rc & "`mweight'"=="" {
		di as error "Error: provide weight"
	}
	else if !_rc &  "`mweight'"=="" {
		local mweight _weight
	}

	if ("`support'"=="") {
		tempvar support
		capture confirm var _support
		if _rc {
			qui g byte `support' = 1
		}
		else qui g byte `support'= _support
	}

	capture confirm var _pscore
	if _rc & "`pscore'"=="" & "`hotel'"!="" {
		di as error "Error: provide propensity score"
		exit 198
	}
	else if !_rc & "`pscore'"=="" & "`hotel'"!=""  {
		tempvar pscore
		qui g double `pscore' = _pscore
	}

	breduc `varlist' , mw(`mweight') tr(`treated') sup(`support') `summary' `quietly' `graph'
end

program define breduc, rclass
syntax varlist(min=1) , MWeight(varname) TReated(varname) SUPport(varname) [summary quietly graph]

	tempvar sumbias sumbias0 _bias0 _biasm xvar

	qui g `_bias0' = .
	qui g `_biasm' = .
	qui g str12 `xvar' = ""
	qui g `sumbias' = .
	qui g `sumbias0' = .

	/* construct header */
	`quietly' di
	`quietly' di as text "{hline 24}{c TT}{hline 34}{c TT}{hline 16}"
	`quietly' di as text "                        {c |}       Mean               %reduct {c |}     t-test"
	`quietly' di as text "    Variable     Sample {c |} Treated Control    %bias  |bias| {c |}    t    p>|t|"
	`quietly' di as text "{hline 24}{c +}{hline 34}{c +}{hline 16}"

	/* calculate stats for varlist */
	tempname m1u m0u v1u v0u m1m m0m bias biasm absreduc tbef taft pbef paft r2bef r2aft chibef chiaft pchibef pchiaft
	local i 0
	foreach v of varlist `varlist' {
		local i = `i' + 1
		qui sum `v' if `treated'==1
		scalar `m1u' = r(mean)
		scalar `v1u' = r(Var)

		qui sum `v' if `treated'==0
		scalar `m0u' = r(mean)
		scalar `v0u' = r(Var)

		qui sum `v' if `treated'==1 & `support'==1
		scalar `m1m' = r(mean)

		qui sum `v' [iw=`mweight'] if `treated'==0 & `support'==1
		scalar `m0m' = r(mean)

		qui replace `xvar' = "`v'" in `i'

		/* standardised % bias before matching */
		scalar `bias' = 100*(`m1u' - `m0u')/sqrt((`v1u' + `v0u')/2)
		qui replace `_bias0' = `bias' in `i'
		qui replace `sumbias0' = abs(`bias') in `i'
		/* standardised % bias after matching */
		scalar `biasm' = 100*(`m1m' - `m0m')/sqrt((`v1u' + `v0u')/2)
		qui replace `_biasm' = `biasm' in `i'
		qui replace `sumbias' = abs(`biasm') in `i'
		/* % reduction in absolute bias */
		scalar `absreduc' = -100*(abs(`biasm') - abs(`bias'))/abs(`bias')

		/* t-tests before matching */
		qui regress `v' `treated'
		scalar `tbef' = _b[`treated']/_se[`treated']
		scalar `pbef' = 2*ttail(e(df_r),abs(`tbef'))
		/* t-tests after matching */
		qui regress `v' `treated' [iw=`mweight'] if `support'==1
		scalar `taft' = _b[`treated']/_se[`treated']
		scalar `paft' = 2*ttail(e(df_r),abs(`taft'))

		`quietly' di as text %12s abbrev("`v'",12) "  Unmatched {c |}" as result %7.0g `m1u' "  " %7.0g `m0u' "  " %7.1f `bias'   _s(8)           as text " {c |}"  as res %7.2f `tbef'  _s(2) as res	 %05.3f `pbef'
		`quietly' di as text              _col(13) "    Matched {c |}" as result %7.0g `m1m' "  " %7.0g `m0m' "  " %7.1f `biasm' %8.1f `absreduc' as text " {c |}" as result %7.2f `taft'  _s(2) as res  %05.3f `paft'
		`quietly' di as text              _col(13) "            {c |}" as text _s(31) "   {c |}"
	}
	`quietly' di as text "{hline 24}{c BT}{hline 34}{c BT}{hline 16}"

	if "`summary'"!="" {
		di as text "{hline 61}"
		di as text _col(10) "Summary of the distribution of the abs(bias)"
		di as text "{hline 61}"
		label var `sumbias0' "BEFORE MATCHING"
		sum `sumbias0', detail
		return scalar meanbiasbef = r(mean)
		return scalar medbiasbef  = r(p50)
		di as text "{hline 61}"
		label var `sumbias' "AFTER MATCHING"
		sum `sumbias', detail
		return scalar meanbiasaft = r(mean)
		return scalar medbiasaft  = r(p50)
		di as text "{hline 61}"

		qui probit `treated' `varlist'
		scalar `r2bef' = e(r2_p)
		scalar `chibef' = e(chi2)
		scalar `pchibef' = chi2tail(e(df_m), e(chi2))
		return scalar r2bef = e(r2_p)
		return scalar chiprobbef = chi2tail(e(df_m), e(chi2))

		qui probit `treated' `varlist' [iw=`mweight'] if `support'==1
		scalar `r2aft' = e(r2_p)
		scalar `chiaft' = e(chi2)
		scalar `pchiaft' = chi2tail(e(df_m), e(chi2))
		return scalar r2aft = e(r2_p)
		return scalar chiprobaft = chi2tail(e(df_m), e(chi2))

		di
		di as text "{hline 12}{c TT}{hline 49}"
		di as text "     Sample {c |}    Pseudo R2      LR chi2        p>chi2"
		di as text "{hline 12}{c +}{hline 49}"
		di as text "  Unmatched {c |}"  _s(4) as res %9.3f `r2bef' _s(4) as res %9.2f `chibef' _s(5) as res %9.3f `pchibef'
		di as text "    Matched {c |}"  _s(4) as res %9.3f `r2aft' _s(4) as res %9.2f `chiaft' _s(5) as res %9.3f `pchiaft'
		di as text "{hline 62}"
	}

	if "`graph'"!="" {
		graph dot `_bias0' `_biasm', over(`xvar', sort(1) descending) legend(label(1 "Unmatched") label(2 "Matched")) yline(0, lcolor(gs10)) marker(1, mcolor(black)  msymbol(O)) marker(2, mcolor(black)  msymbol(X))
	}

end