*! rifsureg 1.1 July 2019 by Fernando Rios Avila * Adds the Mlogit and Mprobit * rifsureg 1.0 June 2019 by Fernando Rios Avila ** This will be a small wrapper to estimate simulataenous RIF regresions. sureg ** biggest problems...indices with double limits. iqr mcs iqshare ** for regressions that may depend on p or q For now only q(#list) *capture program drop rifsureg program rifsureg, eclass sortpreserve byable(recall) if replay() { results exit } syntax anything [if] [in] [aw fw ], qs(str) [,* ] [kernel(str) bw(str)] /// [retain(str) replace /// This is used to save the RIF, and replace if the variable already exists scale(real 1) /// Changes the scale of the RIF. Useful for statistics like GINI and Lorenz ordinate, as they are measured between 0-1 iseed(str) /// Using this, a random variable is created to "sort" data, and avoid (or reduce) the impact of ties, making the results replicable over(varname) /// Indicates to estimate the RIF over two groups. This is can be considered as a partially conditional model. (it is conditional on one variable only) rwlogit(str) rwprobit(str) /// This two options are used to estimate the IPW. rwmlogit(str) rwmprobit(str) /// This two options are used to estimate the IPW. ate att atu /// This indicates which estimator will be done. I would assume ate to be the default ] marksample touse markout `touse' `anything' `abs' `rwprobit' `rwlobit' qui { * y and x's tokenize `anything' local y `1' macro shift local rest `*' ** check fgreg to change names of created variables local expx=regexr("`exp'","=","") if "`expx'"=="" local expx=1 tempvar exp2 gen double `exp2'=`expx' ** We first need to see if the probit model needs to be estimated if (("`rwlogit'"!="")+("`rwprobit'"!="")+("`rwmlogit'"!="")+("`rwmprobit'"!=""))>1 { noisily: display in red "Only one probability model can be set. Choose either logit, probit, mlogit or mprobit for the first stage" exit } ** model selection: *** Over should be a 0 1 variable. if "`rwlogit'"!="" | "`rwprobit'"!="" { if "`over'"=="" { display in red "Over option required to define dependent variable in probit/logit" exit } if (("`ate'"!="") + ("`att'"!="")+("`atu'"!=""))>1 { noisily: display in red "Only one option allowed. Choose ate, att or atu" exit } if "`ate'`att'`atu'"=="" { noisily: display "Neither ate att or atu were selected. Using default average treatment effect ate" local ate ate } tempvar dy qui:egen `dy'=group(`over') if `touse' qui:sum `dy' if `touse' if r(max)>2 { noisily:display in red "More than 2 groups detected. Only 2 groups allowed for the estimator" exit } qui:replace `dy'=`dy'==2 if "`rwprobit'"!="" { qui:probit `dy' `rwprobit' [pw=`exp2'] if `touse'==1 tempvar pr qui:predict double `pr', pr tempname b_rw v_rw matrix `b_rw'=e(b) matrix `v_rw'=e(V) local rwmodel="probit" } if "`rwlogit'"!="" { qui:logit `dy' `rwlogit' [pw=`exp2'] if `touse'==1 tempvar pr qui:predict double `pr', pr tempname b_rw v_rw matrix `b_rw'=e(b) matrix `v_rw'=e(V) local rwmodel="logit" } ** here were do the IPW estimators tempvar ipw qui:gen double `ipw'=(`dy'==1)/`pr'+(`dy'==0)/(1-`pr') if `touse'==1 if "`att'"!="" { qui:replace `ipw'=`ipw'*`pr' } if "`atu'"!="" { qui:replace `ipw'=`ipw'*(1-`pr') } * finally we adjust weights replace `exp2'=`exp2'*`ipw' local weight aw local flag_ipw 1 } ********************************************************************************************** if "`rwmlogit'"!="" | "`rwmprobit'"!="" { if "`over'"=="" { display in red "Over option required to define dependent variable in mprobit/mlogit" exit } if ("`atu'"!="") | ("`att'"!="") { noisily: display in red "ATU or ATT cannot be specified" exit } tempvar dy qui:egen `dy'=group(`over') if `touse' qui:sum `dy' local maxv=r(max) if "`rwmprobit'"!="" { qui:mprobit `dy' `rwmprobit' [pw=`exp2'] if `touse'==1 forvalues i =1/`maxv' { tempvar pr`i' qui:predict double `pr`i'', pr eq(`i') } tempname b_rw v_rw matrix `b_rw'=e(b) matrix `v_rw'=e(V) local rwmodel="mprobit" } if "`rwmlogit'"!="" { qui:mlogit `dy' `rwmlogit' [pw=`exp2'] if `touse'==1 forvalues i =1/`maxv' { tempvar pr`i' qui:predict double `pr`i'', pr eq(`i') } tempname b_rw v_rw matrix `b_rw'=e(b) matrix `v_rw'=e(V) local rwmodel="mlogit" } ** here were do the IPW estimators tempvar ipw qui:gen double `ipw'=0 forvalues i =1/`maxv' { replace `ipw'=`ipw'+(`dy'==`i')*1/`pr`i'' } * finally we adjust weights replace `exp2'=`exp2'*`ipw' local weight aw local flag_ipw 1 } *** numlist "`qs'", min(2) range(>0 <100) sort integer local nml="`r(numlist)'" ** just adds an over. For a more semiparametric, perhaps we can add a smoother parameter. capture drop __`y'_q* foreach qq of local nml { local q : display %02.0f `qq' qui:egen double `retain'__`y'_q`q'=rifvar(`y') if `touse', weight(`exp2') q(`q') seed(`iseed') by(`over') kernel(`kernel') bw(`bw') qui:replace `retain'__`y'_q`q'=`retain'__`y'_q`q'*`scale' } ** scale is used to rescale data to make it easier to read. May be important for share based statistics ** and Gini * MAy also help with poverty indices, if the aim is to find an average gap not as percentage but in poverty line terms. ** changing weight type at the end. *qui sum `rifvar' [aw=`exp2'] if `touse' *local rifmean=r(mean) if "`flag_ipw'"=="" { qui:sureg(`retain'__`y'_q* = `rest') if `touse' [`weight'`exp'], `options' * ereturn local depvar="RIF(`y')" * ereturn local cmd="rifhdreg" * ereturn local cmdline="rifhdreg `0'" * ereturn local rif="`rif'"q * ereturn scalar rifmean=`rifmean' } else { capture drop _wipw_ gen double _wipw_=`exp2' label var _wipw_ "IPW estimated through rifhdreg " qui:sureg(`retain'__`y'_q* = `rest') if `touse' [`weight'=_wipw_], `options' * ereturn local depvar="RIF(`y')" * ereturn local cmd="rifhdreg" * ereturn local cmdline="rifhdreg `0'" * ereturn local rif="`rif'" * ereturn scalar rifmean=`rifmean' } *** eq rename *** number of variables matrix b=e(b) matrix V=e(V) local erank=colsof(b) local nvar= `erank'/e(k_eq) foreach qq of local nml { local q : display %02.0f `qq' local mdfl predict(xb equation(q`q')) `mdfl' local nm `nm' q`q' forvalues i=1/`nvar' { local nm2 `nm2' q`q' } } **renaming matrix matrix coleq b=`nm2' matrix roweq V=`nm2' matrix roweq V=`nm2' ereturn repost b=b V=V, rename buildfvinfo if "`flag_ipw'"=="1" { ereturn matrix b_rw=`b_rw' ereturn matrix V_rw=`v_rw' } ereturn local eqnames="`nm'" ereturn local depvar="`nm'" ereturn local exog="`nm'" ereturn local cmd="rifsureg" ereturn local cmdline="rifsureg `0'" ereturn local marginsdefault="`mdfl'" ereturn local rifwgt="_wipw_" ereturn local rifover="`over'" ereturn local rwmethod "`rwmodel'" } *display "`nm'" ** display results end *capture program drop results program results, eclass if "`e(cmd)'"=="rifsureg" { ereturn local cmd ="sureg" sureg ereturn local cmd="rifsureg" *display "Distributional Statistic: `e(rif)'" *display "Sample Mean RIF `e(rif)' : " in ye %7.5g e(rifmean) } else display in red "last estimates not found" end