iematch help file description

iematch help file description

Finished the first draft of the description section in the help file.

{smcl}
{* }{...}
{hline}
help for {hi:iematch}
{hline}

{title:Title}

{phang2}{cmdab:iematch} {hline 2} Matching base observations towards target observations using on a single continous variable.

{title:Syntax}

{phang2}
{cmdab:iematch}
, {cmdab:grp:dummy(}{it:varname}{cmd:)} {cmdab:match:var(}{it:varname}{cmd:)}
[{cmdab:id:var(}{it:varlist}{cmd:)} {cmdab:m1} {cmdab:maxdiff(}{it:numlist}{cmd:)} {cmdab:seed(}{it:numlist}{cmd:)}
{cmdab:matchid:name(}{it:string}{cmd:)} {cmdab:matchdi:ffname(}{it:string}{cmd:)}
{cmdab:matchre:sultname(}{it:string}{cmd:)} {cmdab:matchco:untname(}{it:string}{cmd:)}
]

{marker opts}{...}
{synoptset 22}{...}
{synopthdr:options}
{synoptline}
{synopt :{cmdab:grp:dummy(}{it:varname}{cmd:)}}The group dummy variable where 1 indicates base observations and 0 target observations{p_end}
{synopt :{cmdab:match:var(}{it:varname}{cmd:)}}The variable with a continous value to match on{p_end}
{synopt :{cmdab:id:var(}{it:varlist}{cmd:)}}The uniquely and fully identifying ID varaible. Used to indicate which target observation a base observation is match with. If omitted an ID variable will be created.{p_end}
{synopt :{cmdab:m1}}Allows many-to-one matches. The default is to allow only one-to-one matches{p_end}
{synopt :{cmdab:maxdiff(}{it:numlist}{cmd:)}}Set a maximum difference allowed in {cmdab:matchvar()}. If a base observation has no match within this difference then it will remain unmatched{p_end}
{synopt :{cmdab:seed(}{it:numlist}{cmd:)}}If seed is not set outside the command (recommended), then this option can be used to set the seed to make matches stable even when multiple observations have the same value in {cmdab:matchvar()}{p_end}
{synopt :{cmdab:matchid:name(}{it:string}{cmd:)}}Manually sets the name of the variable that indicates which target observation each base observation is matched with. The default is _matchID{p_end}
{synopt :{cmdab:matchdi:ffname(}{it:string}{cmd:)}}Manually sets the name of the variable that indicates the differnece in {cmdab:matchvar()} in each match pair/group. The default is _matchDiff{p_end}
{synopt :{cmdab:matchre:sultname(}{it:string}{cmd:)}}Manually sets the name of the variable that indicates if an observation was matched, or provide a reason why it was not. The default is _matchOrReason{p_end}
{synopt :{cmdab:matchco:untname(}{it:string}{cmd:)}}Manually sets the name of the variable that indicates how many observations a target obsersvation is matched with in a many-to-one matches. The default is _matchCount{p_end}
{synoptline}

{title:Description}

{pstd}{cmdab:iematch} matches base observations towards base observations in terms
	of nearest value in {cmd:matchvar()}. Base observations are observations with
	value 1 in {cmd:grpdummy()} and target observations are observations with value
	0. For example, in a typical p-score match, base observations are treatment and target is control, however, there are many other examples of matching where it could
	be different.

{pstd}{cmdab:iematch} base its matching on algorithm on the Stable Marriage algorithm. This algorithm was chosen because it always a solution and because it was possible to implement a stable matching even if multiple observations has identical match values (see {cmd:seed()} option for more details). One disadvantage is of this algorithm is that it only take local efficiency into account and not global. This means that it is possible that other matching algorithms might generate a more efficient match in terms of the sum of the difference of all matched pairs.

{pstd}{hi:{ul:One-to-one matching algorithm}}{p_end}
{pstd}The algorithm used in a one-to-one match starts by evaluating which
	target observation each base observation is closest to and vice versa for target observations. If a base and a target observation pair mutually prefer each other, then those two observations are a match. The algorithm then repeats these two steps but excludes observations after they are matched until all base observations are either matched or excluded due to the option {cmdab:maxdiff()}.

{pstd}In a one-to-one match there have to be at least as many target observations as there are base observation. A one-to-one match returns three variables. One variable indicates the result of the matching for each observation. For example, matched, not matched, no match within the max difference etc. The other two variables hold info on the matched pair. One variable is the ID of the target observation in the match pair, and the other variable is the difference in {cmd:matchvar()} between the two observation in the match pair. See the {help iematch##rtrnvrs:options} for more details.

{pstd}{hi:{ul:Many-to-one matching algorithm}}{p_end}
{pstd}The algorithm used here is the same as in a one-to-one match. But instead of matching only when there is mutual preference, all base observations are matched towards their preferred target observation in the first step, as long as the match is within the max-value if {cmdab:maxdiff()} is used.

{pstd}In a many-to-one match there is no restriction in terms of the number of target observations in relation to base observations. The many-to-one matching results in four variables. Three of the variables are the same as in a one-to-one match. The fourth variable indicates how many base observations that were matched towards each target observation. See the {help iematch##rtrnvrs:options} for more details.

{title:Options}

{phang}{cmdab:grp:dummy(}{it:varname}{cmd:)}

{phang}{cmdab:match:var(}{it:varname}{cmd:)}

{phang}{cmdab:id:var(}{it:varlist}{cmd:)}

{phang}{cmdab:m1}

{phang}{cmdab:maxdiff(}{it:numlist}{cmd:)}

{phang}{cmdab:seed(}{it:numlist}{cmd:)}

{marker rtrnvrs}{...}
{phang}{cmdab:matchid:name(}{it:string}{cmd:)} The names {inp:_ID}, {inp:_matchDiff}, {inp:_matchOrReason} and {inp:_matchCount} are not allowed.

{phang}{cmdab:matchdi:ffname(}{it:string}{cmd:)} The names {inp:_ID}, {inp:_matchID}, {inp:_matchOrReason} and {inp:_matchCount} are not allowed.

{phang}{cmdab:matchre:sultname(}{it:string}{cmd:)} The names {inp:_ID}, {inp:_matchID}, {inp:_matchDiff} and {inp:_matchCount} are not allowed.

{phang}{cmdab:matchco:untname(}{it:string}{cmd:)} The names {inp:_ID}, {inp:_matchID}, {inp:_matchDiff} and {inp:_matchOrReason} are not allowed.

{title:Stored results}

{pstd}
{cmdab:iematch} stores the following results in {hi:r()}:

{title:Examples}

{pstd}
A series of examples on how to specify command, and how to evaluate output:

{pstd}{hi:Example 1.}

{pstd}{hi:Example 2.}

{title:Acknowledgements}

{phang}I would like to acknowledge the help in testing and proofreading I received in relation to this command and help file from (in alphabetic order):{p_end}

{title:Author}

{phang}Kristoffer Bj�rkefur, The World Bank, DECIE

{phang}Please send bug-reports, suggestions and requests for clarifications
		 writing "ietools iematch" in the subject line to:{break}
		 kbjarkefur@worldbank.org

{phang}You can also see the code, make comments to the code, see the version
		 history of the code, and submit additions or edits to the code through
		 the github repository of ietoolkit:{break}
		 {browse "https://github.com/worldbank/ietoolkit"}

{smcl}
{* }{...}
{hline}
help for {hi:iematch}
{hline}

{title:Title}

{phang2}{cmdab:iematch} {hline 2} Matching base observations towards target observations using on a single continous variable.

{title:Syntax}

{phang2}
{cmdab:iematch}
, {cmdab:grp:dummy(}{it:varname}{cmd:)} {cmdab:match:var(}{it:varname}{cmd:)}
[{cmdab:id:var(}{it:varlist}{cmd:)} {cmdab:m1} {cmdab:maxdiff(}{it:numlist}{cmd:)} {cmdab:seed(}{it:numlist}{cmd:)}
{cmdab:matchid:name(}{it:string}{cmd:)} {cmdab:matchdi:ffname(}{it:string}{cmd:)}
{cmdab:matchre:sultname(}{it:string}{cmd:)} {cmdab:matchco:untname(}{it:string}{cmd:)}
]

{marker opts}{...}
{synoptset 22}{...}
{synopthdr:options}
{synoptline}
{synopt :{cmdab:grp:dummy(}{it:varname}{cmd:)}}The group dummy variable where 1 indicates base observations and 0 target observations{p_end}
{synopt :{cmdab:match:var(}{it:varname}{cmd:)}}The variable with a continous value to match on{p_end}
{synopt :{cmdab:id:var(}{it:varlist}{cmd:)}}The uniquely and fully identifying ID varaible. Used to indicate which target observation a base observation is match with. If omitted an ID variable will be created.{p_end}
{synopt :{cmdab:m1}}Allows many-to-one matches. The default is to allow only one-to-one matches{p_end}
{synopt :{cmdab:maxdiff(}{it:numlist}{cmd:)}}Set a maximum difference allowed in {cmdab:matchvar()}. If a base observation has no match within this difference then it will remain unmatched{p_end}
{synopt :{cmdab:seed(}{it:numlist}{cmd:)}}If seed is not set outside the command (recommended), then this option can be used to set the seed to make matches stable even when multiple observations have the same value in {cmdab:matchvar()}{p_end}
{synopt :{cmdab:matchid:name(}{it:string}{cmd:)}}Manually sets the name of the variable that indicates which target observation each base observation is matched with. The default is _matchID{p_end}
{synopt :{cmdab:matchdi:ffname(}{it:string}{cmd:)}}Manually sets the name of the variable that indicates the differnece in {cmdab:matchvar()} in each match pair/group. The default is _matchDiff{p_end}
{synopt :{cmdab:matchre:sultname(}{it:string}{cmd:)}}Manually sets the name of the variable that indicates if an observation was matched, or provide a reason why it was not. The default is _matchOrReason{p_end}
{synopt :{cmdab:matchco:untname(}{it:string}{cmd:)}}Manually sets the name of the variable that indicates how many observations a target obsersvation is matched with in a many-to-one matches. The default is _matchCount{p_end}
{synoptline}

{title:Description}

{pstd}{cmdab:iematch} matches base observations towards base observations in terms
	of nearest value in {cmd:matchvar()}. Base observations are observations with
	value 1 in {cmd:grpdummy()} and target observations are observations with value
	0. In a regular p-score match for example, base observations are treatment and target
	is control, however, there are many other examples of mathcing where it could
	be different.

{pstd}In a one-to-one match there have to be at least as many target obsrevations as
	there are base observation. In a many-to-one match there may be more base observations
	than target observations.

{pstd}The algorithm used in {cmdab:iematch} when performing a one-to-one match is
	based on the Stable Marriage algorithm. The algorithm startes by evaluating which
	target observation each base observation

	from the other group in {cmd:grpdummy()} is closest in terms of the
	variable in {cmd:matchvar()}. If two observations in differnt groups prefer each
	other, then they are a match and they are removed from the data set. The process
	is repeated until all observations with value 1 in group dummy are mathced. This
	algorthm always has a solution and it is implemented to keep the matches stable
	even when mutiple observations share value in {cmd:matchvar()}.

{pstd}When performing a many-to-one match the algorithm does the first step in the
	one-to-one algorithm, and assign all observations with value 1

{pstd}For example,

{title:Options}

{phang}{cmdab:grp:dummy(}{it:varname}{cmd:)}

{phang}{cmdab:match:var(}{it:varname}{cmd:)}

{phang}{cmdab:id:var(}{it:varlist}{cmd:)}

{phang}{cmdab:m1}

{phang}{cmdab:maxdiff(}{it:numlist}{cmd:)}

{phang}{cmdab:seed(}{it:numlist}{cmd:)}

{phang}{cmdab:matchid:name(}{it:string}{cmd:)} The names _ID, _matchDiff, _matchOrReason and _matchCount are not allowed.

{phang}{cmdab:matchdi:ffname(}{it:string}{cmd:)} The names _ID, _matchID, _matchOrReason and _matchCount are not allowed.

{phang}{cmdab:matchre:sultname(}{it:string}{cmd:)} The names _ID, _matchID, _matchDiff and _matchCount are not allowed.

{phang}{cmdab:matchco:untname(}{it:string}{cmd:)} The names _ID, _matchID, _matchDiff and _matchOrReason are not allowed.

{title:Stored results}

{pstd}
{cmdab:iematch} stores the following results in {hi:r()}:

{title:Examples}

{pstd}
A series of examples on how to specify command, and how to evaluate output:

{pstd}{hi:Example 1.}

{pstd}{hi:Example 2.}

{title:Acknowledgements}

{phang}I would like to acknowledge the help in testing and proofreading I received in relation to this command and help file from (in alphabetic order):{p_end}

{title:Author}

{phang}Kristoffer Bjrkefur, The World Bank, DECIE

{phang}Please send bug-reports, suggestions and requests for clarifications
		 writing "ietools iematch" in the subject line to:{break}
		 kbjarkefur@worldbank.org

{phang}You can also see the code, make comments to the code, see the version
		 history of the code, and submit additions or edits to the code through
		 the github repository of ietoolkit:{break}
		 {browse "https://github.com/worldbank/ietoolkit"}


docs/cookbook/c: missing quote char.

docs/cookbook/c: missing quote char.

redo-ifchange arches configure redoconf/utils.sh

config() {
	local dir="$1" arch="$2"
	shift
	shift
	[ -d "$dir" ] || mkdir "$dir"
	(
		cd "$dir" &&
		../configure --host="$arch" "$@" &&
		echo "$dir"
	)
}

dirs=$(
	for d in $(cat arches); do
		if [ "$d" = "native" ]; then
			arch=""
		else
			arch="$d"
		fi
		config "out.$d" "$arch"
		config "out.$d.static" "$arch" "--enable-static"
		config "out.$d.opt" "$arch" "--enable-optimization"
	done
)

for dir in $dirs; do
	echo "$dir/rc/CC.rc"
done | xargs redo-ifchange

for dir in $dirs; do
	( cd "$dir" &&
	  set --;
	  . ./redoconf.rc &&
	  rc_include rc/CC.rc &&
	  [ -n "$HAVE_CC" ] &&
	  echo "$dir"
	) || (echo "Skipping '$dir' - no working C compiler." >&2)
done >$3

wait

redo-ifchange arches configure redoconf/utils.sh

config() {
	local dir="$1" arch="$2"
	shift
	shift
	[ -d "$dir" ] || mkdir "$dir"
	(
		cd "$dir" &&
		../configure --host="$arch" "$@" &&
		echo "$dir"
	)
}

dirs=$(
	for d in $(cat arches); do
		if [ "$d" = "native" ]; then
			arch=""
		else
			arch="$d"
		fi
		config "out.$d" "$arch"
		config "out.$d.static" "$arch" "--enable-static"
		config "out.$d.opt" "$arch" "--enable-optimization"
	done
)

for dir in $dirs; do
	echo "$dir/rc/CC.rc"
done | xargs redo-ifchange

for dir in $dirs; do
	( cd "$dir" &&
	  set --;
	  . ./redoconf.rc &&
	  rc_include rc/CC.rc &&
	  [ -n "$HAVE_CC" ] &&
	  echo "$dir"
	) || (echo "Skipping $dir' - no working C compiler." >&2)
done >$3

wait


Updated repo path in example do-file.

Updated repo path in example do-file.

version 9

//ssc install estout

sysuse auto, clear
estimates clear

regress weight length
estimates store est1

stgit ..
esttab est1 using mytable.csv, replace nonotes ///
	addnotes("Git branch: `r(branch)'" "Git SHA of last commit: `r(sha)'")

version 9

//ssc install estout

sysuse auto, clear
estimates clear

regress weight length
estimates store est1

stgit .
esttab est1 using mytable.csv, replace nonotes ///
	addnotes("Git branch: `r(branch)'" "Git SHA of last commit: `r(sha)'")


Removed typos

Removed typos

	*Set standardized settings
	ieboilstart, v(11.1)
	`r(version)'

	*Create filepaths
	global ietoolkit "C:\Users\wb503680\Box Sync\DIME WOrk\GitFolder\ietoolkit"
	*global ietoolkit "C:\Users\wb462869\Box Sync\Stata\Stata work\Commands\ietoolkit"
	global testOutput "$ietoolkit/test/ieimpgraphOutput"

	*Set cd folder to catch and cd leakage
	cd "$ietoolkit\test\cdjunk"

	*Load the command
	do "$ietoolkit\iegraph.do"

	pause on

	**********************
	*Graph 1 - single treatment

	*open an example data set and create a mock dummy
	sysuse auto, clear
	gen Treatment = (weight >= 3019.5)

	*Run the impact regression
	reg price  Treatment
	*Create the graph
	iegraph Treatment, noconfbars title("Treatment effect on price")  save("$testOutput/Graph1.gph") yzero grey
	pause
	iegraph Treatment, title("Treatment effect on price") save("$testOutput/Graph1.gph") yzero grey
	pause

	**********************
	*Graph 2 - multiple treatment

	*open an example data set and create mutually exclusive mock dummies
	sysuse auto, clear
	tab rep78, gen(d_)

	*Run the impact regression
	reg price	d_2 d_3 weight length gear_ratio
	*Create the graph

	iegraph 	d_2 d_3,  title("Treatment effect on price") save("$testOutput/Graph2.gph") yzero

	reg price	d_2 d_3 d_4  weight length gear_ratio
	iegraph 	d_2 d_3 d_4, title("Treatment effect") save("$testOutput/Graph4.gph") yzero note("Stata iegraph command")

	reg price	d_2 d_3 d_4 d_5  weight length gear_ratio
	iegraph 	d_2 d_3 d_4 d_5, noconfbars title("Treatment effect on price") save("$testOutput/Graph2.gph") yzero

	iegraph d_2 d_3,  title("Treatment effect on price") save("$testOutput/Graph2.gph") yzero
	iegraph d_2 d_3 d_4,  title("Treatment effect") save("$testOutput/Graph4.gph") yzero note(Stata iegraph command)
	iegraph d_2 d_3 d_4 d_5,  noconfbars title("Treatment effect on price") save("$testOutput/Graph2.gph") yzero

	*Set standardized settings
	ieboilstart, v(11.1)
	`r(version)'

	*Create filepaths
	global ietoolkit "C:\Users\wb503680\Box Sync\DIME WOrk\GitFolder\ietoolkit"
	*global ietoolkit "C:\Users\wb462869\Box Sync\Stata\Stata work\Commands\ietoolkit"
	global testOutput "$ietoolkit/test/ieimpgraphOutput"

	*Set cd folder to catch and cd leakage
	cd "$ietoolkit\test\cdjunk"

	*Load the command
	do "$ietoolkit\iegraph.do"

	pause on

	**********************
	*Graph 1 - single treatment

	*open an example data set and create a mock dummy
	sysuse auto, clear
	gen Treatment = (weight >= 3019.5)

	*Run the impact regression
	reg price  Treatment
	*Create the graph
	iegraph Treatment, noconfbars title("Treatment effect on price")  save("$testOutput/Graph1.gph") yzero grey
	pause
	iegraph Treatment, title("Treatment effect on price") save("$testOutput/Graph1.gph") yzero grey
	pause

	**********************
	*Graph 2 - multiple treatment

	*open an example data set and create mutually exclusive mock dummies
	sysuse auto, clear
	tab rep78, gen(d_)

	*Run the impact regression
	reg price	d_2 d_3 weight length gear_ratio
	*Create the graph

	iegraph 	d_2 d_3,  title("Treatment effect on price") save("$testOutput/Graph2.gph") yzero

	reg price	d_2 d_3 d_4  weight length gear_ratio
	iegraph 	d_2 d_3 d_4, title("Treatment effect") save("$testOutput/Graph4.gph") yzero note("Stata iegraph command")

	reg price	d_2 d_3 d_4 d_5  weight length gear_ratio
	iegraph 	d_2 d_3 d_4 d_5, noconfbars title("Treatment effect on price") save("$testOutput/Graph2.gph") yzero

	iegraph d_2 d_3,  title("Treatment effect on price") save("$testOutput/Graph2.gph") yzero
	iegraph d_2 d_3 d_4,  title("Treatment effect") save("$testOutput/Graph4.gph") yzero note(Stata Command iegraph. copyright KBjark)
	iegraph d_2 d_3 d_4 d_5,  noconfbars title("Treatment effect on price") save("$testOutput/Graph2.gph") yzero


semester

semester

program ddchart

use ${stash}panelfips, clear

// need to exclude early months because of sparse data
// TODO! Far from complete, come back to this.

est clear
use ${stash}panelfips, clear

gen semester = hofd(dofm(month))
format semester %th

eststo: xtpoisson numuser 1.treat##b2007.year if month > 550, fe vce(robust)
estimates save ${myestimates}dd_numuser, replace

eststo: xtpoisson numuser 1.treat##b95.semester, fe vce(robust)
estimates save ${myestimates}dd_numuser, replace

drawchart numuser 2006

end

program drawchart

local var `1'
local cutoff `2'

estimates use ${myestimates}dd_`var'
qui parmest, label list(parm estimate min* max* p) saving(${stash}pars_tmp, replace)

clear
use ${stash}pars_tmp, clear

keep if regexm(parm, "1.*treat.*semester.*") == 1
gen semester = regexs(1) if regexm(parm, ".*#([0-9][0-9][0-9]?)b?\..*")

destring semester, replace
replace semester = semester - 95
label variable semester "Half-Year"

qui gen xaxis = 0
* list estimate min max month

graph twoway (connected estimate semester, msize(small) lpattern(solid) lcolor(edkblue) lwidth(thin)) (line min semester, lwidth(vthin) lpattern(-) lcolor(gs8)) (line max semester, lwidth(vthin) lpattern(-) lcolor(gs8)) (line xaxis semester, lwidth(vthin) lcolor(gs8)) if semester > -4, xline(0) legend(off) title("") xtitle("Semester")

graph export ${tables}timeline_`var'.eps, replace
shell epstopdf ${tables}timeline_`var'.eps

end

program old
est clear
use ${stash}panelfips, clear
eststo: xtpoisson numuser 1.treat##b573.month if month > 550, fe vce(robust)

eststo: xtpoisson numuser 1.treat##b2007.year if month > 550, fe vce(robust)

estimates save ${myestimates}dd_numuser, replace

est clear
use ${stash}panelfips, clear
eststo: xtreg numuser 1.treat##b573.month, fe vce(robust)
estimates save ${myestimates}dd_numnewusers, replace

est clear
use ${stash}panelfips, clear
eststo: xtpoisson numcontrib 1.treat##b573.month if month > 550, fe vce(robust)
estimates save ${myestimates}dd_numcontrib, replace

est clear
use ${stash}panelfips, clear
eststo: xtpoisson numserious90 1.treat##b573.month if month > 564, fe vce(robust)
estimates save ${myestimates}dd_numserious90, replace

drawchart numuser -15
drawchart numnewusers -8
drawchart numcontrib -15
drawchart numserious90 -15
end

program ddchart

use ${stash}panelfips, clear

// need to exclude early months because of sparse data
// TODO! Far from complete, come back to this.

est clear
use ${stash}panelfips, clear

gen quarter = qofd(dofm(month))
format quarter %tq

eststo: xtpoisson numuser 1.treat##b2007.year if month > 550, fe vce(robust)
estimates save ${myestimates}dd_numuser, replace

eststo: xtpoisson numuser 1.treat##b191.quarter fe vce(robust)

drawchart numuser 2006

end

program drawchart

local var `1'
local cutoff `2'

estimates use ${myestimates}dd_`var'
qui parmest, label list(parm estimate min* max* p) saving(${stash}pars_tmp, replace)

clear
use ${stash}pars_tmp, clear

keep if regexm(parm, "1.*treat.*year.*") == 1
gen year = regexs(1) if regexm(parm, ".*#([0-9][0-9][0-9][0-9])b?\..*")

destring year, replace
replace year = year - 2007

qui gen xaxis = 0
* list estimate min max month

graph twoway (connected estimate year, msize(small) lpattern(solid) lcolor(edkblue) lwidth(thin)) (line min year, lwidth(vthin) lpattern(-) lcolor(gs8)) (line max year, lwidth(vthin) lpattern(-) lcolor(gs8)) (line xaxis year, lwidth(vthin) lcolor(gs8)) if year > -2, xline(0) legend(off) title("") xtitle("Year")

graph export ${tables}timeline_`var'.eps, replace
shell epstopdf ${tables}timeline_`var'.eps

end

program old
est clear
use ${stash}panelfips, clear
eststo: xtpoisson numuser 1.treat##b573.month if month > 550, fe vce(robust)

eststo: xtpoisson numuser 1.treat##b2007.year if month > 550, fe vce(robust)

estimates save ${myestimates}dd_numuser, replace

est clear
use ${stash}panelfips, clear
eststo: xtreg numuser 1.treat##b573.month, fe vce(robust)
estimates save ${myestimates}dd_numnewusers, replace

est clear
use ${stash}panelfips, clear
eststo: xtpoisson numcontrib 1.treat##b573.month if month > 550, fe vce(robust)
estimates save ${myestimates}dd_numcontrib, replace

est clear
use ${stash}panelfips, clear
eststo: xtpoisson numserious90 1.treat##b573.month if month > 564, fe vce(robust)
estimates save ${myestimates}dd_numserious90, replace

drawchart numuser -15
drawchart numnewusers -8
drawchart numcontrib -15
drawchart numserious90 -15
end


Update iegitaddmd.ado

Update iegitaddmd.ado

Fixed recursive call (still called iegitaddtxt) and added all option as in issue #101

cap program drop   iegitaddmd
	program define iegitaddmd

	qui {

		syntax , folder(string) [all]

		*Test that folder exist
		mata : st_numscalar("r(dirExist)", direxists("`folder'"))

		if `r(dirExist)' == 0 {

			noi di as error `"{phang}The "`folder'" folder does not exist. You must enter the full path. For example, on most Windows computers it starts with {it:C:} and on most Mac computers with {it:/user/}. Important: Specify the whole file path to the repository folder, not just {it:C:} or {it:/user/} as that would creaet the .txt file in every empty folder on your computer.{p_end}"'
			error 693
			exit
		}

		*List files, directories and other files
		local flist : dir `"`folder'"' files "*"
		local dlist : dir `"`folder'"' dirs "*"
		local olist : dir `"`folder'"' other "*"

		*Test if all of those lists are empty.
		if `"`flist'`dlist'`olist'"' == "" | ("`all'" == "all") {

			** If all those lists are empty then we are in an
			*  empty folder and should write README.md
			writeGitKeep `"`folder'"'

		}

		*Use the command on each subfolder to this folder (if any)
		foreach dir of local dlist {

			*Recursive call on each subfolder
			iegitaddmd , folder(`"`folder'//`dir'"')
		}
	}

end

*Write a README.md file iegitaddmd have found an empty folder
cap program drop   writeGitKeep
	program define writeGitKeep

		args folder

		*Create file
		tempname 	newHandle
		cap file close 	`newHandle'
			file open  	`newHandle' using "`folder'/README.md", text write replace

		*Add some text to the file
		file write  `newHandle' ///
			_col(4)"*******************************************************************************" _n ///
			_col(4)"*******************************************************************************" _n _n ///
			_col(8) "This file is only a placeholder file so that GitHub syncs empty folders!" _n _n ///
			_col(8) "If files have been added to the folder of this file so that this" _n ///
			_col(8) "file is no longer the only file in this folder, then this file" _n ///
			_col(8) "may be deleted. " _n _n ///
			_col(4)"*******************************************************************************" _n ///
			_col(4)"*******************************************************************************" _n ///
			_n

		*Closing the file
		file close 		`newHandle'

end

cap program drop   iegitaddmd
	program define iegitaddmd

	qui {

		syntax , folder(string)

		*Test that folder exist
		mata : st_numscalar("r(dirExist)", direxists("`folder'"))

		if `r(dirExist)' == 0 {

			noi di as error `"{phang}The "`folder'" folder does not exist. You must enter the full path. For example, on most Windows computers it starts with {it:C:} and on most Mac computers with {it:/user/}. Important: Specify the whole file path to the repository folder, not just {it:C:} or {it:/user/} as that would creaet the .txt file in every empty folder on your computer.{p_end}"'
			error 693
			exit
		}

		*List files, directories and other files
		local flist : dir `"`folder'"' files "*"
		local dlist : dir `"`folder'"' dirs "*"
		local olist : dir `"`folder'"' other "*"

		*Test if all of those lists are empty.
		if `"`flist'`dlist'`olist'"' == "" {

			** If all those lists are empty then we are in an
			*  empty folder and should write README.md
			writeGitKeep `"`folder'"'

		}

		*Use the command on each subfolder to this folder (if any)
		foreach dir of local dlist {

			*Recursive call on each subfolder
			iegitaddtxt , folder(`"`folder'//`dir'"')
		}
	}

end

*Write a README.md file iegitaddmd have found an empty folder
cap program drop   writeGitKeep
	program define writeGitKeep

		args folder

		*Create file
		tempname 	newHandle
		cap file close 	`newHandle'
			file open  	`newHandle' using "`folder'/README.md", text write replace

		*Add some text to the file
		file write  `newHandle' ///
			_col(4)"*******************************************************************************" _n ///
			_col(4)"*******************************************************************************" _n _n ///
			_col(8) "This file is only a placeholder file so that GitHub syncs empty folders!" _n _n ///
			_col(8) "If files have been added to the folder of this file so that this" _n ///
			_col(8) "file is no longer the only file in this folder, then this file" _n ///
			_col(8) "may be deleted. " _n _n ///
			_col(4)"*******************************************************************************" _n ///
			_col(4)"*******************************************************************************" _n ///
			_n

		*Closing the file
		file close 		`newHandle'

end