*! v.2 		04/18/2013		Estimation of the Standard Error of Delta 0 much more efficient		By: Alejandro Hoyos

****weights
capture program drop weights
program define weights
version 10.1
	{
	syntax varlist(min=1) [if], by(string) [fact(string)]

	tempvar _fexp
	quietly gen `_fexp' = 1


	if "`fact'"!="" {
		quietly replace `_fexp' = `fact'
	}

	tempvar _sample
	if "`if'"!=""{

	quietly gen `_sample' = 1 `if'
	}

	if "`if'"==""{
	quietly gen `_sample' = 1
	}

	*generate cells
	tempvar _celda
	quietly egen `_celda'=group(`varlist')

	quietly replace `_celda' = .  if `_sample'!=1

	*generate supports
	tempvar _nopomin _nopomax
	quietly gen _supp=.
	quietly bys `_celda': egen `_nopomax' = max(`by')
	quietly bys `_celda': egen `_nopomin' = min(`by')
  	quietly replace _supp = 0 if `_nopomax' == 0 & `_sample'==1
  	quietly replace _supp = 1 if `_nopomin' == 1 & `_sample'==1
  	quietly replace _supp = 2 if `_nopomin' == 0 & `_nopomax' == 1 & `_sample'==1

	*generate matching weight
	tempvar _prevfm _fm _prevfh _fh
	quietly bys `_celda' `by': egen `_prevfm' = total(`_fexp')
	quietly replace `_prevfm' = . if `_sample'!=1
	quietly replace `_prevfm' = . if `by'==1
	quietly bys `_celda': egen `_fm' = mean(`_prevfm')
	quietly replace `_fm' = . if `_sample'!=1

	quietly bys `_celda' `by': egen `_prevfh' = total(`_fexp')
	quietly replace `_prevfh' = . if `_sample'!=1
	quietly replace `_prevfh' = . if `by'==0
	quietly bys `_celda': egen `_fh' = mean(`_prevfh')
	quietly replace `_fh' = . if `_sample'!=1

	quietly gen _match = .
	quietly replace _match = `_fexp' if `by'==0 & _supp==2 & `_sample'==1
	quietly replace _match = `_fexp'*`_fm'/`_fh' if `by'==1 & _supp==2 & `_sample'==1
	quietly replace _match = 0 if _supp==0 | _supp==1 & `_sample'==1
	lab var _supp  "Support"
	lab var _match "Weight after matching"

	cap label define _supplabel 0 "Category by-variable=0 out of the common support"
	cap label define _supplabel 1 "Category by-variable=1 out of the common support", add
	cap label define _supplabel 2 "In the common support", add
	cap label values _supp _supplabel
	}
end


**Deltas
capture program drop deltas
program define deltas
version 10.1
	{
	syntax varlist [if], match(string) outcome(string) supp(string) by(string) [fact(string)] [filename(string)]

	tempfile main
	quietly save `main', replace

	tempvar _sample
	if "`if'"!=""{
	quietly gen `_sample' = 1 `if'
	}
	if "`if'"==""{
	quietly gen `_sample' = 1
	}

	tempvar _fexp
	quietly gen `_fexp' = 1

	if "`fact'"!="" {
	quietly replace `_fexp' = `fact'
	}


	*******************
	*Compute Deltas
	********************
	*generate rwage
	cap drop _rwage
	quietly sum `outcome' if `by'==0 & `_sample'==1 [iw =`_fexp']
	quietly gen _rwage=`outcome'/ r(mean) if `_sample'==1
	quietly drop if _rwage==. & `_sample'==1
	lab var _rwage "Outcome - normalized"

	quietly summ `by' if `by'==0 & `_sample'==1 [iw= `_fexp']
	local _TF=r(sum_w)
	quietly summ `by' if `by'==1 & `_sample'==1 [iw= `_fexp']
	local _TM=r(sum_w)
	quietly summ `supp' if `supp'==0 & `_sample'==1 [iw=`_fexp']
	local _outF=r(sum_w)
	quietly summ `supp' if `supp'==1 & `_sample'==1 [iw=`_fexp']
	local _outM=r(sum_w)
	quietly summ `supp' if `supp'==2 & `by'==0 & `_sample'==1 [iw=`_fexp']
	local _commF=r(sum_w)
	quietly summ `supp' if `supp'==2 & `by'==1 & `_sample'==1 [iw=`_fexp']
	local _commM=r(sum_w)

	local _percM=`_commM' / `_TM'
	local _percF=`_commF' / `_TF'

	local _ratio1=`_outM' / `_TM'
	local _ratio0=`_outF' / `_TF'

	*** DELTA
	qui su _rwage if `by'==1 & `_sample'==1 [iw = `_fexp']
	local _rwage1=r(mean)
	qui su _rwage if `by'==0 & `_sample'==1 [iw = `_fexp']
	local _rwage0=r(mean)
	local _D = `_rwage1'-`_rwage0'

	*** DELTA 0
	qui su _rwage [iw=`match'] if `by'==1 & `_sample'==1
	local _rwage1=r(mean)
	qui su _rwage [iw=`match'] if `by'==0 & `_sample'==1
	local _rwage0=r(mean)
	local _D0 = `_rwage1'-`_rwage0'

	*** DELTA M
	qui su _rwage [iw=`_fexp'] if `by'==1 & `supp'==1 & `_sample'==1
	local _rwage1=r(mean)
	qui su _rwage [iw=`_fexp'] if `by'==1 & `supp'==2 & `_sample'==1
	local _rwage0=r(mean)
	local _DM = (`_rwage1'-`_rwage0')*`_ratio1'

	*** DELTA F
	qui su _rwage [iw=`_fexp'] if `by'==0 & `supp'==2 & `_sample'==1
	local _rwage1=r(mean)
	qui su _rwage [iw=`_fexp'] if `by'==0 & `supp'==0 & `_sample'==1
	local _rwage0=r(mean)
	local _DF = (`_rwage1'-`_rwage0')*`_ratio0'

	*** DELTA X
	qui su _rwage [iw=`match'] if `by'==1 & `supp'==2 & `_sample'==1
	local _rwage1=r(mean)
	qui su _rwage [iw=`_fexp'] if `by'==1 & `supp'==2 & `_sample'==1
	local _rwage0=r(mean)
	local _DX = `_rwage0'-`_rwage1'


	display in green "*****************************************************************"
	display in green "*****  Gap in `varlist' decomposition"
	display in green "*****************************************************************"
	display in yellow "D  =" `_D'
	display in yellow "D0 =" `_D0'
	display in yellow "DM =" `_DM'
	display in yellow "DF =" `_DF'
	display in yellow "DX =" `_DX'
	display in green "*****************************************************************"
	display in yellow "percM =" `_percM'
	display in yellow "percF =" `_percF'
	display in green "*****************************************************************"

	use `main', clear

	if "`filename'"!="" {
	tempfile main
	quietly save `main', replace
	quietly clear
	quietly set obs 1
	quietly gen controls = "`varlist'"
	quietly gen D = `_D'
	quietly gen D0 = `_D0'
	quietly gen DM = `_DM'
	quietly gen DF = `_DF'
	quietly gen DX = `_DX'
	quietly gen percM = `_percM'
	quietly gen percF = `_percF'
	quietly save "`filename'.dta", replace
	quietly use `main', clear
	}
	}
end

**Standard Errors
capture program drop sderrors2
program define sderrors2, rclass
version 10.1
	{
	syntax varlist(min=1) [if], outcome(string) supp(string) by(string) [fact(string)]

	tempfile main
	quietly save `main', replace
	if "`if'"!=""{
	quietly keep `if'
	}

	tempvar _fexp
	quietly gen `_fexp' = 1

	if "`fact'"!="" {
	quietly replace `_fexp' = `fact'
	}


	**gen rwage
	cap drop _rwage
	quietly sum `outcome' if `by'==0  [iw =`_fexp']
	quietly gen _rwage=`outcome'/ r(mean)
	quietly drop if _rwage==.
	lab var _rwage "Outcome - normalized"


	quietly keep if `supp'==2

	quietly count
	if (r(N)==0){
		display in yellow "Std.error can not be calculated by lack of common support"
		return scalar _dev=.
	}

	if (r(N)!=0){
	/*alfa = Nf/Nm*/
	quietly summ `_fexp' if `by'==1
	local _Nm = r(sum)
	quietly summ `_fexp' if `by'==0
	local _Nf = r(sum)
	local _alpha = `_Nf'/`_Nm'


	/*tamanios sin factores de expansion*/
	quietly count if `by'==1
	local _nm = _result(1)
	quietly count if `by'==0
	local _nf = _result(1)

	/*Variance of the second term of the right hand side of equation 9*/
	quietly summ _rwage if `by'==0 [iw=`_fexp']
	local _total0 = _result(4)/`_nf'

	/*Now I construct the first term*/
	/*1. The sample proportion of females that exhibit the set of caracteristics*/

	preserve
	quietly keep if `by'==0
	collapse (sum) `_fexp', by(`varlist')
	rename `_fexp' _nfcelda
	quietly gen _wf = _nfcelda/`_Nf'
	sort `varlist'
	tempfile tempo
	quietly save `tempo', replace
	restore

	/*2. The sample average of earnings for males that exhibit the set of characteristics*/

	preserve
	quietly keep if `by'==1
	collapse (mean) _rwage [iw=`_fexp'], by (`varlist')
	rename _rwage _ym
	sort `varlist'
	quietly merge `varlist' using `tempo'
	quietly tab _merge
	quietly keep if _merge==3
	drop _merge
	sort `varlist'
	quietly count
	quietly save `tempo', replace
	restore

	/*the population variance of male wages that exhibit the set of characteristics*/

	preserve
	quietly keep if `by'==1
	collapse (sd) _rwage [iw=`_fexp'], by (`varlist')
	quietly gen _varym = (_rwage)^2
	drop _rwage
	sort `varlist'
	quietly merge `varlist' using `tempo'
	quietly tab _merge
	quietly keep if _merge==3
	drop _merge
	sort `varlist'
	quietly count
	tempfile collapsed
	quietly save `collapsed', replace

	quietly gen _part1=(_wf*(1-_wf)*(_ym^2))/((`_alpha')^2)+_varym*(_wf^2)
	quietly summ _part1
	local _total1=(r(sum))/`_nm'

	quietly count
	local _K=_result(1) /*numero de celdas*/
	local _total2=0
	local _j=1
	quietly gen _wfym=_wf*_ym
	quietly egen _sumwfym1 = sum(_wfym)
	quietly gen _sumwfym2 = _sumwfym1 - _wfym
	quietly gen _sumwfym3 = _sumwfym2*_wfym

	quietly sum _sumwfym3
	local _total2 = r(sum)/2

	quietly drop _wfym _sumwfym1 _sumwfym2 _sumwfym3


	local _total2 = 2*(`_total2')/((`_nm')*((`_alpha')^2))

	local _dev = sqrt(`_total0'+`_total1'-`_total2')
	display in yellow "Std.error DO = " `_dev'
	return scalar _dev= `_dev'

	restore
	}

u `main', clear
}
end


***nopomatch
capture program drop nopomatch
program define nopomatch
version 10.1
{
	syntax varlist(min=1) [if], outcome(string) by(string) [sd] [replace] [reportby(string)] [fact(string)] [filename(string)]
	if "`replace'"!=""{
		cap drop _match
		cap drop _supp
	}

	quietly drop if `outcome'==.

	weights `varlist' `if', by(`by') fact(`fact')

	tempfile mainfile
	quietly save `mainfile', replace

	if "`reportby'"=="" {
		deltas `varlist' `if', outcome(`outcome') match(_match) supp(_supp) by(`by') fact(`fact') filename(`filename')
		if "`sd'"!="" {
			display in green "Calculating Standard Error"
			sderrors2 `varlist' `if', outcome(`outcome') supp(_supp) by(`by') fact(`fact')
			local _sd =r(_dev)
			if "`filename'"!=""{
					tempfile temp
					quietly save `temp', replace
					u "`filename'", clear
					quietly gen sdev = `_sd'
					quietly save "`filename'", replace
 					u `temp', clear
 			}
		}

	}

	if "`reportby'"!="" {
		tempfile mainfile
		quietly save `mainfile', replace

		tempfile temp
		quietly tostring `reportby', replace force
		quietly save `temp', replace
		levelsof `reportby', local(_levels)
		local _i = 1

		foreach x of local _levels{
			display in green "`reportby' = `x'"
			if "`filename'"==""{
				if "`if'"!=""{
					deltas `varlist' `if' & `reportby'=="`x'", outcome(`outcome') match(_match) supp(_supp) by(`by') fact(`fact')
				}
				if "`if'"==""{
					deltas `varlist' if `reportby'=="`x'", outcome(`outcome') match(_match) supp(_supp) by(`by') fact(`fact')
				}
			}
			if "`filename'"!=""{

				if "`if'"!=""{
					deltas `varlist' `if' & `reportby'=="`x'", outcome(`outcome') match(_match) supp(_supp) by(`by') fact(`fact') filename(`filename'_`x')
				}
				if "`if'"==""{
					deltas `varlist' if `reportby'=="`x'", outcome(`outcome') match(_match) supp(_supp) by(`by') fact(`fact') filename(`filename'_`x')
				}
				u "`filename'_`x'", clear
				quietly gen category="`x'"
				quietly save "`filename'_`x'", replace
				#delimit ;
				if `_i'==1 {; qui save "`filename'", replace; quietly erase "`filename'_`x'.dta"; };
				if `_i'!=1 {; quietly append using "`filename'"; sort category; qui save "`filename'", replace; quietly erase "`filename'_`x'.dta";};
				#delimit cr
				label var category "Category of `reportby'"
				u `temp', clear
			}

			tempfile temp
			quietly save `temp', replace

			if "`sd'"!=""{
				display in green "Calculating Standard Error"
				if "`if'"!=""{
					sderrors2 `varlist' `if' & `reportby'=="`x'", outcome(`outcome') supp(_supp) by(`by') fact(`fact')
				}
				if "`if'"==""{
					sderrors2 `varlist' if `reportby'=="`x'", outcome(`outcome') supp(_supp) by(`by') fact(`fact')
				}
				local _sd  =r(_dev)

				if "`filename'"!=""{
					#delimit ;
					if `_i'==1 {; clear; quietly set obs 1; quietly gen category = "`x'"; quietly gen sdev = `_sd'; tempfile sderrors2; sort category; quietly save `sderrors2', replace;};
					if `_i'!=1 {; clear; quietly set obs 1; quietly gen category = "`x'"; quietly gen sdev = `_sd'; append using `sderrors2'; sort category; quietly save `sderrors2', replace;};
					#delimit cr
					u `temp', clear
				}
			}
		local _i = `_i'+1
		}

		**merge gaps with standard errors
		if "`filename'"!=""  &  "`sd'"!="" {
			quietly u "`filename'", clear
			sort category
			quietly merge category using `sderrors2'
			sort category
			quietly drop _merge
			quietly save "`filename'", replace
		}
		quietly u `mainfile', clear
	}
}

end