iegraph: adding syntax lines that were not merged properly

*! version 6.0 19OCT2018 DIME Analytics dimeanalytics@worldbank.org

cap	program drop	iegraph
	program define 	iegraph, rclass

	syntax varlist, 							///
 	   [noconfbars 								///
 		confbarsnone(varlist) 					///
 		confintval(numlist min=1 max=1 >0 <1) 	///
 		BARLabel								///
 		MLABColor(string)						///
 		MLABPosition(numlist)					///
 		MLABSize(string)						///
 		BAROPTions(string)						///
 		barlabelformat(string)					///
 		GREYscale								///
 		yzero									///
 		BASICTItle(string) 						///
 		VARLabels								///
 		ignoredummytest 						///
 		norestore								///
 		save(string) *]

 	if "`restore'" == "" preserve

	qui {

	version 11

/*******************************************************************************

						Identify options used

********************************************************************************/

	*Checking to see if the noconfbars option has been used and assigning 1 and 0 based
	*on that to the CONFINT_BAR variable.
	if "`confbars'" != ""  			local CONFINT_BAR 	= 0
	if "`confbars'" == ""  			local CONFINT_BAR 	= 1

	*Checking to see if the barlabel option has been used and assigning 1 and 0 based
	*on that to the LABEL_BAR variable.
	if "`barlabel'" != "" 			local LABEL_BAR 	= 1
	if "`barlabel'" == "" 			local LABEL_BAR 	= 0

	*Checking to see if the mlabposition option has been used and assigning 1 and 0 based
	*on that to the LABEL_POS variable.
	if "`mlabposition'" != "" 		local LABEL_POS 	= 1
	if "`mlabposition'" == "" 		local LABEL_POS 	= 0

	*Checking to see if the mlabcolor option has been used and assigning 1 and 0 based
	*on that to the LABEL_COL variable.
	if "`mlabcolor'" != "" 			local LABEL_COL 	= 1
	if "`mlabcolor'" == "" 			local LABEL_COL 	= 0

	*Checking to see if the mlabcolor option has been used and assigning 1 and 0 based
	*on that to the LABEL_COL variable.
	if "`mlabsize'" != "" 			local LABEL_SIZE	= 1
	if "`mlabsize'" == "" 			local LABEL_SIZE 	= 0

	*Checking to see if the barlabelformat option has been used and assigning 1 and 0 based
	*on that to the LABEL_FORMAT variable.
	if "`barlabelformat'" != "" 	local LABEL_FORMAT 	= 1
	if "`barlabelformat'" == ""		local LABEL_FORMAT 	= 0

/*******************************************************************************

							Prepare inputs

********************************************************************************/

	*Only keep the observations in the regressions
	keep if e(sample) == 1

	*Copy beta matrix to a regular matrix
	mat BETA = e(b)

	*Translate GREYscale to GRAYscale
	if "`greyscale'" != "" local grayscale "grayscale"

	*Unabbreviate and varlists
	unab varlist : `varlist'

	*Testing to see if the variables used in the regressions are actual dummy variables as treatment vars need to be dummy variables.
	foreach var of local varlist {

		*Get the column number from this var
		local colnumber = colnumb(BETA,"`var'")

		*Test if this var was omitted from the regression
		if "`r(label`colnumber')'" == "(omitted)" {

			*Test if that dummy is not found in the estimation matrix
			noi di as error "{phang}Dummy variable `var' was not included in the regression, or was omitted from it.{p_end}"
			error 480
		}
	}

	foreach var of local varlist {
		*Assigning variable coefficient/standard errors/no of obs. to scalars with the name Coeff_(`variable name')
		*coeff_se_(`variable name'), obs_(`variable name').

		*Access and store the beta value (
		scalar coeff_`var' 		= _b[`var']

		*Access and store standard errors for the dummy
		scalar coeff_se_`var' 	= _se[`var']

		*Store the number of observations for this dummy
		count if `var' == 1 //Count one tmt group at the time
		scalar obs_`var' = r(N)

	}

	*Test if the list of dummies are valid
	if "`ignoredummytest'" == "" testDums `varlist'

	*Testing to see if the variables used in confbarsnone are
	*actually in the list of
	*variables used for the regression/graph.
	local varTest : list confbarsnone in varlist

	if `varTest' == 0 {
		*Error displayed if variables defined in confbarsnone aren't in the list of variables for the graph.
		noi display as error "{phang} Variables defined in confbarsnone(`confbarsnone') cannot be found in the graph variable list. {p_end}"
		noi display ""
		error 111
	}

	* Can only be used if the bar label is displayed
	if `LABEL_BAR' == 0 {
		if `LABEL_FORMAT' | `LABEL_POS' | `LABEL_COL' | `LABEL_SIZE' {
			noi display as error "{phang} Options barlabelformat(), mlabsize(), mlabposition() and mlabcolor() can only be specified when option barlabel is used. {p_end}"
			error 198
		}
	}
	else {

		**************************************
		* Check that specified format is valid
		**************************************

		if `LABEL_FORMAT' {
			if substr("`barlabelformat'",1,1) != "%" | !inlist(substr("`barlabelformat'",-1,1), "e", "f") | !regex("`barlabelformat'", "\.") {
				noi display as error "{phang} Option barlabelformat() was incorrectly specified. Only fixed and exponencial formats are currently allowed. See {help format} for more information on how to specify a variable format.{p_end}"
				error 198
			}
		}

		***************************************************************************
		* Check that label options are valid. If not, print warning and turn switch
		* off so default will be used
		***************************************************************************
		if `LABEL_POS' {
			noi 	clockname `mlabposition'
			local 	LABEL_POS = r(LABEL_POS)
		}
		if `LABEL_SIZE' {
			noi 	sizename `mlabsize'
			local 	LABEL_SIZE = r(LABEL_SIZE)
		}
		if `LABEL_COL' {
			if !inlist("`mlabcolor'", "background", "bg", "foreground", "fg") {
				noi 	colorname `mlabcolor'
				local 	LABEL_COL = r(LABEL_COL)
			}
		}
	}

	*Checking to see if the save option is used what is the extension related to it.
	if "`save'" != "" {

		**Find the last . in the path name and assume that
		* the file extension is what follows. However, with names
		* that have multiple dots in it, the user has to explicitly
		* specify the file name.

		**First, will extract the file names from the combination of file
		* path and files names. We will use both backslash and forward slash
		* to account for differences in Windows/Unix file paths
		local backslash = strpos(reverse("`save'"), "\")
		local forwardslash = strpos(reverse("`save'"), "/")

		** Replacing the value of forward/back slash with the other value if one of the
		*  values is equal to zero.
        if `forwardslash' == 0  local forwardslash = `backslash'
        if `backslash' == 0     local backslash = `forwardslash'

		**Extracting the file name from the full file path by  reversing and breaking the path
		* at the first occurence of slash.
		local file_name = substr(reverse("`save'"), 1, (min(`forwardslash', `backslash')-1))
		local file_name = reverse("`file_name'")

		**If no slashes it means that there is no file path and just a file name, so the name of the file will be
		* the local save.
		if (`forwardslash' == 0 & `backslash' == 0) local file_name = "`save''"

		*Assign the full file path to the local file_suffix
		local file_suffix = "`file_name'"

        *Find index for where the file type suffix start
        local dot_index     = strpos("`file_name'",".")

		local file_suffix = substr("`file_name'", `dot_index' + 1, .)

		*If no dot in the name, then no file extension
		if `dot_index' == 0 {
			local save `"`save'.gph"'
			local file_suffix "gph"
			local save_export = 0
		}

		**If there is one or many . in the file path than loop over
		* the file path until we have found the last one.

		**Find index for where the file type suffix starts. We are re-checking
		* to see if there are any more dots than the first one. If there are,
		* then there needs to be an error message saying remove the dots.
		local dot_index 	= strpos("`file_suffix'",".")

		*Extract the file index

		if (`dot_index' > 0) {
			di as error "{pstd}File names cannot have more than one dot. Please only use the dot to separate the filename and file format.{p_end}"
			error 198
		}

        *List of formats to which the file can be exported
        local nonGPH_formats png tiff gph ps eps pdf wmf emf

        *If no file format suffix is specified, use the default .gph
        if "`file_suffix'" == "gph" {
			local save_export = 0
		}

        *If a file format suffix is specified make sure that it is one of the eight formats allowed.
        else if `:list file_suffix in nonGPH_formats' != 0  {
            local save_export = 1

			if ("`file_suffix'" == "wmf" | "`file_suffix'" == "emf") & "`c(os)'" != "Windows" {
				di as error "{pstd}The file formats .wmf and .emf are only allowed when using Stata on a Windows computer.{p_end}"
                error 198
			}
		}
		*If a different extension was used then display an error.
        else {

            di as error "{pstd}You are not using a allowed file format in save(`save'). Only the following formats are allowed: gph `nonGPH_formats'. {p_end}"
            error 198
        }
    }
	else {

		*Save option is not used, therefore save export will not be used
		local save_export = 0

	}

	* Set default barlabel options
	if `LABEL_BAR' {
		if !`LABEL_POS'		local mlabposition 	12
		if !`LABEL_COL'	 	local mlabcolor		black
		if !`LABEL_SIZE' 	local mlabsize		medium
	}

/*******************************************************************************

						Get values from regression

*******************************************************************************/

	local count: word count `varlist' // Counting the number of total vars used as treatment.
	local graphCount = `count' + 1 // Number of vars needed for the graph is total treatment vars plus one(control).

	//Make all vars tempvars (maybe do later)
	//Make sure that missing is properly handled

	tempvar anyTMT control
	egen `anyTMT' = rowmax(`varlist')
	gen `control' = (`anyTMT' == 0) 	if !missing(`anyTMT')

	sum `e(depvar)' if `control' == 1
	scalar ctl_N		= r(N)
	scalar ctl_mean	  	= r(mean)
	scalar ctl_mean_sd 	= r(sd)

	/**
	 Calculate t-statistics
	**/

	*If not set in options, use default of 95%
	if "`confintval'" == "" {
		local confintval = .95
	}

	**Since we calculating each tail separately we need to convert
	* the two tail % to one tail %
	local conintval_1tail = ( `confintval' + (1-`confintval' ) / 2)

	*degrees of freedom in regression
	local df = `e(df_r)'

	*Calculate t-stats to be used
	local tstats = invt(`df' , `conintval_1tail'  )

	foreach var of local varlist {

		*Calculating confidnece interval
		scalar  conf_int_min_`var'   =	(coeff_`var'-(`tstats'*coeff_se_`var') + ctl_mean)
		scalar  conf_int_max_`var'   =	(coeff_`var'+(`tstats'*coeff_se_`var') + ctl_mean)
		**Assigning stars to the treatment vars.

		*Perform the test to get p-values
		test `var'
		local star_`var' " "

		scalar  pvalue =r(p)
		if pvalue < 0.10 {
			local star_`var' "*"
		}
		if pvalue < 0.05 {
			local star_`var' "**"
		}
		if pvalue < 0.01 {
			local star_`var' "***"
		}

		scalar tmt_mean_`var' = ctl_mean + coeff_`var'
	}

/*******************************************************************************

			Set up temp file where results are written

*******************************************************************************/

	tempfile		 newTextFile
	tempname 		 newHandle
	cap file close 	`newHandle'
	file open  		`newHandle' using "`newTextFile'", text write append

	*Write headers and control value
	file write `newHandle' ///
		"position" 	_tab "xLabeled"	_tab "mean" _tab "coeff" _tab "conf_int_min" _tab "conf_int_max" _tab "obs" _tab "star" _n 	///
		%9.3f (1) _tab "Control"  _tab %9.3f (ctl_mean)      _tab  	_tab   _tab _tab %9.3f (ctl_N) 	 _tab  _n

	tempvar newCounter
	gen `newCounter' = 2  //First tmt group starts at 2 (1 is control)

	foreach var in `varlist' {

		if "`varlabels'" == "" {

			*Default is to use the varname in legend
			local var_legend "`var'"

		}
		else {

			*Option to use the variable label in the legend instead
			local var_legend : variable label `var'

		}

		*Writing the necessary tables for the graph to list to file.
	    if `: list var in confbarsnone' {
			file write `newHandle' 	%9.3f (`newCounter') _tab `"`var_legend'"'  ///
			_tab %9.3f (tmt_mean_`var') _tab  %9.3f (coeff_`var')  _tab _tab ///
			_tab %9.3f (obs_`var') _tab "`star_`var''"  _n

			replace `newCounter' = `newCounter' + 1
		}
		else {
			file write `newHandle' %9.3f (`newCounter') _tab `"`var_legend'"' ///
			_tab %9.3f (tmt_mean_`var') _tab  %9.3f (coeff_`var')  			///
			_tab %9.3f (conf_int_min_`var') _tab %9.3f (conf_int_max_`var')	///
			_tab %9.3f (obs_`var')   _tab "`star_`var''"  _n

			replace `newCounter' = `newCounter' + 1
		}
	}

	file close `newHandle'

/*******************************************************************************

						Create the graph

*******************************************************************************/

	*Read file with results
	insheet using `newTextFile', clear

	*Defining various options to go on the graph option.

	local tmtGroupBars 	""
	local xAxisLabels 	`"xlabel( "'
	local legendLabels	""
	local legendNumbers	""

	forval tmtGroupCount = 1/`graphCount' {

		************
		*Create the bar for this group

		if "`grayscale'" == "" {
			colorPicker `tmtGroupCount' `graphCount'
		}
		else {
			grayPicker `tmtGroupCount' `graphCount'
		}

		local tmtGroupBars `"`tmtGroupBars' (bar mean position if position == `tmtGroupCount', `baroptions' color("`r(color)'") lcolor(black) ) "'

		************
		*Create labels etc. for this group

		local obs 			= obs[`tmtGroupCount']
		local stars 		= star[`tmtGroupCount']
		local legendLabel 	= xlabeled[`tmtGroupCount']

		local xAxisLabels 	`"`xAxisLabels' `tmtGroupCount' "(N = `obs') `stars'" "'
		local legendLabels 	`"`legendLabels' lab(`tmtGroupCount' "`legendLabel'") "'
		local legendNumbers	`"`legendNumbers' `tmtGroupCount'"'
	}

	*Close or complete some strings
	local xAxisLabels `"`xAxisLabels' ,noticks labsize(medsmall)) "'
	local legendOption `"legend(order(`legendNumbers') `legendLabels')"'

	*Create the confidence interval bars

	if `CONFINT_BAR' == 0 {

		local confIntGraph = ""
	}
		else if `CONFINT_BAR' == 1 {
		local confIntGraph = `"(rcap conf_int_max conf_int_min position, lc(gs)) (scatter mean position,  msym(none)  mlabsize(`mlabsize') mlabposition(`mlabposition') mlabcolor(`mlabcolor'))"'
	}

	*Create the bar label
	if `LABEL_BAR' == 0 {
		local barLabel = ""
	}
	else if `LABEL_BAR' == 1 {

		gen label = mean

		if `LABEL_FORMAT' == 1 {
			format label `barlabelformat'
		}
		else if `LABEL_FORMAT' == 0 {
			format label %9.1f
		}

		local barLabel = `"(scatter mean position,  msym(none)  mlab(label) mlabposition(`mlabposition') mlabcolor(`mlabcolor'))"'
	}

	local titleOption `" , xtitle("") ytitle("`e(depvar)'") "'

	if "`save'" != "" {
		local saveOption saving("`save'", replace)
	}

	*******************************************************************************
	*** Generating the graph axis labels for the [yzero] option used..
	*******************************************************************************

	*Calculations needed if yzero used
	if  ("`yzero'" != "" ) {

		**Testing if [yzero] is applicable
		********************************

		** [yzero] is only applicable if all values used in the graph
		* are all negative or all positive. If there is a mix, then
		* the [yzero] option will be ignored

		*Finding the min value for all values used in the graph
		gen row_minvalue = min(mean, conf_int_min, conf_int_max)
		sum row_minvalue
		local min_value `r(min)'

		*Finding the min value for all values used in the graph
		gen row_maxvalue = max(mean , conf_int_max, conf_int_min)
		sum row_maxvalue
		local max_value `r(max)'

		*Locals used for logic below
		local signcheck = ((`max_value' * `min_value') >= 0) 	// dummy local for both signs the same (positive or negative)
		local negative	=  (`max_value' <= 0)				// dummy for max value still negative (including 0)

		**If [yzero] is used and min and max does not have
		* the same sign, then [yzero] is not applicable.

		if (`signcheck' == 0 ) {

		**** [yzero] is NOT applicable and will be ignored
		*************************************************

			noi di "{pstd}{error:WARNING:} Option yzero will be ignored as the graph has values both on the the positve and negative part of the y-axis. This only affects formatting of the graph. See helpfile for more details.{p_end}"
		}
		else {

		**** [yzero] is applicable and will be used
		*****************************************

			*Get max value if only postive values
			if (`negative' == 0) {

				sum row_maxvalue
				local absMax = `max_value'
			}

			*Get absolute min (will convert back below) if only negative values
			else {

				sum row_minvalue
				local absMax = abs(`min_value')
			}

			*Rounded up to the nearest power of ten
			local logAbsMax = ceil(log10(`absMax'))
			local absMax = 10 ^ (`logAbsMax')

			*Generating quarter value for y-axis markers.
			local quarter = (`absMax') / 4

			**Construct the option to be applied to
			* the graph using the values calculated
			if (`negative' == 0)  {

				local yzero_option ylabel(0(`quarter')`absMax')
			}
			else {

				local absMax = `absMax' * (-1) // Convert back to negative
				local yzero_option ylabel(`absMax'(`quarter')0)
			}
		}
	}

	*******************************************************************************
	***Graph generation based on if the option [save] has an export or a save feature.
	*******************************************************************************

	*Store all the options in one local
	local commandline 		`" `tmtGroupBars' `confIntGraph' `barLabel' `titleOption'  `legendOption' `xAxisLabels' title("`basictitle'") `yzero_option' `options'  "'

	*Error message used in both save-option cases below.
	local graphErrorMessage `" Something went wrong while trying to generate the graph. Click {stata di r(cmd) :display graph options } to see what graph options iegraph used. This can help in locating the source of the error in the command. "'

	if `save_export' == 0 {

		*Generate a return local with the code that will be used to generate the graph
		return local cmd `"graph twoway `commandline' `saveOption'"'

		*Generate the graph
		cap graph twoway `commandline' `saveOption'

		*If error, provide error message and then run the code again allowing the program to crash
		if _rc {

			di as error "{pstd}`graphErrorMessage'{p_end}"
            graph twoway `commandline' `saveOption'
		}
	}
	else if `save_export' == 1 {

		*Generate a return local with the code that will be used to generate the graph
		return local cmd `"graph twoway `commandline'"'

		*Generate the graph
		cap graph twoway `commandline'

		*If error, provide error message and then run the code again allowing the program to crash
		if _rc {

			di as error "{pstd}`graphErrorMessage'{p_end}"
            graph twoway `commandline'
		}

		*Export graph to preferred option
		graph export "`save'", replace

	}

	if "`restore'" == "" restore
}

end
	*******************************************
	*******************************************
		******* To pick colors based  *******
		******* on the number of vars *******
	*******************************************
	*******************************************
	cap	program drop	colorPicker
		program define 	colorPicker , rclass

		args groupCount totalNumGroups

		if `totalNumGroups' == 2 {

			if `groupCount' == 1 return local color "215 25 28"
			if `groupCount' == 2 return local color "43 123 182"
		}
		else if `totalNumGroups' == 3 {

			if `groupCount' == 1 return local color "215 25 28"
			if `groupCount' == 2 return local color "255 255 191"
			if `groupCount' == 3 return local color "43 123 182"
		}
		else if `totalNumGroups' == 4 {

			if `groupCount' == 1 return local color "215 25 28"
			if `groupCount' == 2 return local color "255 255 191"
			if `groupCount' == 3 return local color "171 217 233"
			if `groupCount' == 4 return local color "43 123 182"
		}
		else {

			*For five or more colors we repeat the same pattern

			local colorNum = mod(`groupCount', 5)
			if `colorNum' == 1 return local color "215 25 28"
			if `colorNum' == 2 return local color "253 174 93"
			if `colorNum' == 3 return local color "255 255 191"
			if `colorNum' == 4 return local color "171 217 233"
			if `colorNum' == 0 return local color "43 123 182"

		}

	end

	*******************************************
	*******************************************
		******* Grayscale Option *******
		******* Colour Picker    *******
	*******************************************
	*******************************************

	cap	program drop	grayPicker
		program define 	grayPicker , rclass

		args groupCount totalNumGroups

		if `groupCount' == 1 {

			return local color "black"
		}

		else if `groupCount' == 2 & `totalNumGroups' <= 3 {

			return local color "gs14"
		}
		else {

			local grayscale =  round( (`groupCount'-1) * (100 / (`totalNumGroups'-1) ))

			return local color "`grayscale' `grayscale' `grayscale' `grayscale'"
		}

	end

	*******************************************
	*******************************************
		******* Test if valid  *******
		******* dummies 	   *******
	*******************************************
	*******************************************

	cap program drop 	testDums
		program define	testDums

		unab dumlist : `0'

		foreach dumvar of varlist `dumlist' {

			*Test: all values dummies (missing would have been excluded in regression and we keep if e(sample)
			cap assert inlist(`dumvar',0,1)
			if _rc {
				noi display as error "{phang} The variable `dumvar' is not a dummy. Treatment variable needs to be a dummy (0 or 1) variable. {p_end}"
				noi display ""
				error 149
			}
		}

		/*What we are testing for below:
			- We count the number of dummies that each obervation has the value 1 for.
			- The count numbers must either fit the case of diff-in-diff or the case of regression with one dummy for each treatment arms

			Regular regression with one dummy for each treatment arm
			- Some observations don't have 1 for any dummy - omitted control observations
			- No observation has the value 1 in more than one observation - can't be in more than one treatment group
			- No treatment group can have no observation with value 1 for that dummy

			Diff-in-Diff
			- Some observations don't have 1 for any dummy - omitted controls observations in time = 0
			- Some observation must have value 1 for only the treatment dummy - treatment observations in time = 0
			- Some observation must have value 1 for only the time dummy - control observations in time = 1
			- Some observation must have value 1 for in all three of time, treatment and interaction dummy - treatment observations in time = 1

		*/

		*Count how many dummies is 1 for each observation
		tempvar  dum_count
		egen 	`dum_count' = rowtotal(`dumlist')

		*Exactly one dummy is 1, meaning this observation is in one of the treatment arms
		count if `dum_count' == 1
		local dum_count_1 `r(N)'

		*No dummies is 1, meaning this observation is control
		count if `dum_count' == 0
		local dum_count_0 `r(N)'

		*Exactly 3 dummies are three. Only allowed in the exact case of diff-and-diff regressions
		count if `dum_count' == 3
		local dum_count_3 `r(N)'

		*Exactly 2 or more than three is never correct.
		count if `dum_count' == 2 | `dum_count' > 3
		local dum_count_2orgt3 `r(N)'

		*Test that there are at least some treatment observations
		if `dum_count_0' == 0 		noi di as error "{phang} There are no control observations. One category must be omitted and it should be the omitted category in the regression. The omitted category will be considerd the control group. See helpfile for more info. Disable this test by using option ignoredummytest.{p_end}"
		if `dum_count_0' == 0 		error 480

		*Test that there are at least some control observations (this error should be caught by dummies omitted in the regression)
		if `dum_count_1' == 0 		noi di as error "{phang} There are no treatment observations. None of the dummies have observations for which the dummy has the value 1. See helpfile for more info. Disable this test by using option ignoredummytest.{p_end}"
		if `dum_count_1' == 0 		error 480

		*Test if there are any observations that have two or more than three dummies that is 1
		if `dum_count_2orgt3' > 0 	noi di as error "{phang} There is overlap in the treatment dummies. The dummies must be mutually exclusive meaning that no observation has the value 1 in more than one treatment dummy. The exception is when you use a diff-and-diff, but this dummies is not a valid diff and diff. See helpfile for more info. Disable this test by using option ignoredummytest.{p_end}"
		if `dum_count_2orgt3' > 0 	error 480

		*After passing the previous two steps, test if there are cases that are only allowed in diff
		if `dum_count_3' > 0 {

			*Diff-and-diff must have exactly 3 dummies
			if `:list sizeof dumlist' != 3 	noi di as error "{phang} There is overlap in the treatment dummies. The dummies must be mutually exclusive meaning that no observation has the value 1 in more than one treatment dummy. The exception is when you use a diff-and-diff, but this dummies is not a valid diff and diff. See helpfile for more info. Disable this test by using option ignoredummytest.{p_end}"
			if `:list sizeof dumlist' != 3 	error 480

			* Test if valid diff-diff
			testDumsDD `dum_count' `dumlist'
		}

	end

	cap program drop 	testDumsDD
		program define	testDumsDD

		local dum_count `1'

		**Test that for only two of three dummies there are observations
		* that has only that dummy. I.e. the two that is not the
		* interaction. If the interaction is 1, all three shluld be 1.

		*Count how many dummies the condition is above applies to
		local counter 0

		*Loop over all dummies
		forvalues i = 2/4 {

			*Test the number
			count if ``i'' == 1 & `dum_count' == 1
			if `r(N)' > 0 local ++counter

		}
		*Count that exactly two dummies fullfilled the condition
		if `counter' != 2	noi di as error "{phang} There is overlap in the treatment dummies. The dummies must be mutually exclusive meaning that no observation has the value 1 in more than one treatment dummy. The exception is when you use a diff-and-diff, but this dummies is not a valid diff and diff. See helpfile for more info. Disable this test by using option ignoredummytest.{p_end}""
		if `counter' != 2	error 480

	end

	* Test inputs for label
	cap prog drop sizename
 		prog def sizename, rclass

		args name

		capture findfile gsize-`name'.style

		if ( _rc == 601 ) {

			noi di "{phang} WARNING: Option mlabsize() was incorrectly specified. Only {help textsizestyle} values are accepted. Default size used.{p_end}"
			return local 	LABEL_SIZE 	0
		}

	end

	cap prog drop colorname
		prog def colorname, rclass

		args name

		capture findfile color-`name'.style

		if ( _rc == 601 ) {

			noi di "{phang} WARNING: Option mlabcolor() was incorrectly specified. Only named colors in {help colorstyle} are accepted. Default color used.{p_end}"
			return local 	LABEL_COL 	0
		}

	end

	cap prog drop clockname
		prog def clockname, rclass

		args name

		capture findfile clockdir-`name'.style

		if ( _rc == 601 ) {

			noi di "{phang} WARNING: Option mlabposition() was incorrectly specified. Only {help clockposstyle} values are accepted. Default position used.{p_end}"
			return local 	LABEL_POS 	0
		}

	end

*! version 6.0 19OCT2018 DIME Analytics dimeanalytics@worldbank.org

cap	program drop	iegraph
	program define 	iegraph, rclass

	syntax varlist, [noconfbars BASICTItle(string) save(string) ignoredummytest confbarsnone(varlist) 	///
						confintval(numlist min=1 max=1 >0 <1) VARLabels BAROPTions(string) norestore  	///
						GREYscale GRAYscale yzero *]

	if "`restore'" == "" preserve

	qui {

	version 11

/*******************************************************************************

						Identify options used

********************************************************************************/

	*Checking to see if the noconfbars option has been used and assigning 1 and 0 based
	*on that to the CONFINT_BAR variable.
	if "`confbars'" != ""  			local CONFINT_BAR 	= 0
	if "`confbars'" == ""  			local CONFINT_BAR 	= 1

	*Checking to see if the barlabel option has been used and assigning 1 and 0 based
	*on that to the LABEL_BAR variable.
	if "`barlabel'" != "" 			local LABEL_BAR 	= 1
	if "`barlabel'" == "" 			local LABEL_BAR 	= 0

	*Checking to see if the mlabposition option has been used and assigning 1 and 0 based
	*on that to the LABEL_POS variable.
	if "`mlabposition'" != "" 		local LABEL_POS 	= 1
	if "`mlabposition'" == "" 		local LABEL_POS 	= 0

	*Checking to see if the mlabcolor option has been used and assigning 1 and 0 based
	*on that to the LABEL_COL variable.
	if "`mlabcolor'" != "" 			local LABEL_COL 	= 1
	if "`mlabcolor'" == "" 			local LABEL_COL 	= 0

	*Checking to see if the mlabcolor option has been used and assigning 1 and 0 based
	*on that to the LABEL_COL variable.
	if "`mlabsize'" != "" 			local LABEL_SIZE	= 1
	if "`mlabsize'" == "" 			local LABEL_SIZE 	= 0

	*Checking to see if the barlabelformat option has been used and assigning 1 and 0 based
	*on that to the LABEL_FORMAT variable.
	if "`barlabelformat'" != "" 	local LABEL_FORMAT 	= 1
	if "`barlabelformat'" == ""		local LABEL_FORMAT 	= 0

/*******************************************************************************

							Prepare inputs

********************************************************************************/

	*Only keep the observations in the regressions
	keep if e(sample) == 1

	*Copy beta matrix to a regular matrix
	mat BETA = e(b)

	*Translate GREYscale to GRAYscale
	if "`greyscale'" != "" local grayscale "grayscale"

	*Unabbreviate and varlists
	unab varlist : `varlist'

	*Testing to see if the variables used in the regressions are actual dummy variables as treatment vars need to be dummy variables.
	foreach var of local varlist {

		*Get the column number from this var
		local colnumber = colnumb(BETA,"`var'")

		*Test if this var was omitted from the regression
		if "`r(label`colnumber')'" == "(omitted)" {

			*Test if that dummy is not found in the estimation matrix
			noi di as error "{phang}Dummy variable `var' was not included in the regression, or was omitted from it.{p_end}"
			error 480
		}
	}

	foreach var of local varlist {
		*Assigning variable coefficient/standard errors/no of obs. to scalars with the name Coeff_(`variable name')
		*coeff_se_(`variable name'), obs_(`variable name').

		*Access and store the beta value (
		scalar coeff_`var' 		= _b[`var']

		*Access and store standard errors for the dummy
		scalar coeff_se_`var' 	= _se[`var']

		*Store the number of observations for this dummy
		count if `var' == 1 //Count one tmt group at the time
		scalar obs_`var' = r(N)

	}

	*Test if the list of dummies are valid
	if "`ignoredummytest'" == "" testDums `varlist'

	*Testing to see if the variables used in confbarsnone are
	*actually in the list of
	*variables used for the regression/graph.
	local varTest : list confbarsnone in varlist

	if `varTest' == 0 {
		*Error displayed if variables defined in confbarsnone aren't in the list of variables for the graph.
		noi display as error "{phang} Variables defined in confbarsnone(`confbarsnone') cannot be found in the graph variable list. {p_end}"
		noi display ""
		error 111
	}

	* Can only be used if the bar label is displayed
	if `LABEL_BAR' == 0 {
		if `LABEL_FORMAT' | `LABEL_POS' | `LABEL_COL' | `LABEL_SIZE' {
			noi display as error "{phang} Options barlabelformat(), mlabsize(), mlabposition() and mlabcolor() can only be specified when option barlabel is used. {p_end}"
			error 198
		}
	}
	else {

		**************************************
		* Check that specified format is valid
		**************************************

		if `LABEL_FORMAT' {
			if substr("`barlabelformat'",1,1) != "%" | !inlist(substr("`barlabelformat'",-1,1), "e", "f") | !regex("`barlabelformat'", "\.") {
				noi display as error "{phang} Option barlabelformat() was incorrectly specified. Only fixed and exponencial formats are currently allowed. See {help format} for more information on how to specify a variable format.{p_end}"
				error 198
			}
		}

		***************************************************************************
		* Check that label options are valid. If not, print warning and turn switch
		* off so default will be used
		***************************************************************************
		if `LABEL_POS' {
			noi 	clockname `mlabposition'
			local 	LABEL_POS = r(LABEL_POS)
		}
		if `LABEL_SIZE' {
			noi 	sizename `mlabsize'
			local 	LABEL_SIZE = r(LABEL_SIZE)
		}
		if `LABEL_COL' {
			if !inlist("`mlabcolor'", "background", "bg", "foreground", "fg") {
				noi 	colorname `mlabcolor'
				local 	LABEL_COL = r(LABEL_COL)
			}
		}
	}

	*Checking to see if the save option is used what is the extension related to it.
	if "`save'" != "" {

		**Find the last . in the path name and assume that
		* the file extension is what follows. However, with names
		* that have multiple dots in it, the user has to explicitly
		* specify the file name.

		**First, will extract the file names from the combination of file
		* path and files names. We will use both backslash and forward slash
		* to account for differences in Windows/Unix file paths
		local backslash = strpos(reverse("`save'"), "\")
		local forwardslash = strpos(reverse("`save'"), "/")

		** Replacing the value of forward/back slash with the other value if one of the
		*  values is equal to zero.
        if `forwardslash' == 0  local forwardslash = `backslash'
        if `backslash' == 0     local backslash = `forwardslash'

		**Extracting the file name from the full file path by  reversing and breaking the path
		* at the first occurence of slash.
		local file_name = substr(reverse("`save'"), 1, (min(`forwardslash', `backslash')-1))
		local file_name = reverse("`file_name'")

		**If no slashes it means that there is no file path and just a file name, so the name of the file will be
		* the local save.
		if (`forwardslash' == 0 & `backslash' == 0) local file_name = "`save''"

		*Assign the full file path to the local file_suffix
		local file_suffix = "`file_name'"

        *Find index for where the file type suffix start
        local dot_index     = strpos("`file_name'",".")

		local file_suffix = substr("`file_name'", `dot_index' + 1, .)

		*If no dot in the name, then no file extension
		if `dot_index' == 0 {
			local save `"`save'.gph"'
			local file_suffix "gph"
			local save_export = 0
		}

		**If there is one or many . in the file path than loop over
		* the file path until we have found the last one.

		**Find index for where the file type suffix starts. We are re-checking
		* to see if there are any more dots than the first one. If there are,
		* then there needs to be an error message saying remove the dots.
		local dot_index 	= strpos("`file_suffix'",".")

		*Extract the file index

		if (`dot_index' > 0) {
			di as error "{pstd}File names cannot have more than one dot. Please only use the dot to separate the filename and file format.{p_end}"
			error 198
		}

        *List of formats to which the file can be exported
        local nonGPH_formats png tiff gph ps eps pdf wmf emf

        *If no file format suffix is specified, use the default .gph
        if "`file_suffix'" == "gph" {
			local save_export = 0
		}

        *If a file format suffix is specified make sure that it is one of the eight formats allowed.
        else if `:list file_suffix in nonGPH_formats' != 0  {
            local save_export = 1

			if ("`file_suffix'" == "wmf" | "`file_suffix'" == "emf") & "`c(os)'" != "Windows" {
				di as error "{pstd}The file formats .wmf and .emf are only allowed when using Stata on a Windows computer.{p_end}"
                error 198
			}
		}
		*If a different extension was used then display an error.
        else {

            di as error "{pstd}You are not using a allowed file format in save(`save'). Only the following formats are allowed: gph `nonGPH_formats'. {p_end}"
            error 198
        }
    }
	else {

		*Save option is not used, therefore save export will not be used
		local save_export = 0

	}

	* Set default barlabel options
	if `LABEL_BAR' {
		if !`LABEL_POS'		local mlabposition 	12
		if !`LABEL_COL'	 	local mlabcolor		black
		if !`LABEL_SIZE' 	local mlabsize		medium
	}

/*******************************************************************************

						Get values from regression

*******************************************************************************/

	local count: word count `varlist' // Counting the number of total vars used as treatment.
	local graphCount = `count' + 1 // Number of vars needed for the graph is total treatment vars plus one(control).

	//Make all vars tempvars (maybe do later)
	//Make sure that missing is properly handled

	tempvar anyTMT control
	egen `anyTMT' = rowmax(`varlist')
	gen `control' = (`anyTMT' == 0) 	if !missing(`anyTMT')

	sum `e(depvar)' if `control' == 1
	scalar ctl_N		= r(N)
	scalar ctl_mean	  	= r(mean)
	scalar ctl_mean_sd 	= r(sd)

	/**
	 Calculate t-statistics
	**/

	*If not set in options, use default of 95%
	if "`confintval'" == "" {
		local confintval = .95
	}

	**Since we calculating each tail separately we need to convert
	* the two tail % to one tail %
	local conintval_1tail = ( `confintval' + (1-`confintval' ) / 2)

	*degrees of freedom in regression
	local df = `e(df_r)'

	*Calculate t-stats to be used
	local tstats = invt(`df' , `conintval_1tail'  )

	foreach var of local varlist {

		*Calculating confidnece interval
		scalar  conf_int_min_`var'   =	(coeff_`var'-(`tstats'*coeff_se_`var') + ctl_mean)
		scalar  conf_int_max_`var'   =	(coeff_`var'+(`tstats'*coeff_se_`var') + ctl_mean)
		**Assigning stars to the treatment vars.

		*Perform the test to get p-values
		test `var'
		local star_`var' " "

		scalar  pvalue =r(p)
		if pvalue < 0.10 {
			local star_`var' "*"
		}
		if pvalue < 0.05 {
			local star_`var' "**"
		}
		if pvalue < 0.01 {
			local star_`var' "***"
		}

		scalar tmt_mean_`var' = ctl_mean + coeff_`var'
	}

/*******************************************************************************

			Set up temp file where results are written

*******************************************************************************/

	tempfile		 newTextFile
	tempname 		 newHandle
	cap file close 	`newHandle'
	file open  		`newHandle' using "`newTextFile'", text write append

	*Write headers and control value
	file write `newHandle' ///
		"position" 	_tab "xLabeled"	_tab "mean" _tab "coeff" _tab "conf_int_min" _tab "conf_int_max" _tab "obs" _tab "star" _n 	///
		%9.3f (1) _tab "Control"  _tab %9.3f (ctl_mean)      _tab  	_tab   _tab _tab %9.3f (ctl_N) 	 _tab  _n

	tempvar newCounter
	gen `newCounter' = 2  //First tmt group starts at 2 (1 is control)

	foreach var in `varlist' {

		if "`varlabels'" == "" {

			*Default is to use the varname in legend
			local var_legend "`var'"

		}
		else {

			*Option to use the variable label in the legend instead
			local var_legend : variable label `var'

		}

		*Writing the necessary tables for the graph to list to file.
	    if `: list var in confbarsnone' {
			file write `newHandle' 	%9.3f (`newCounter') _tab `"`var_legend'"'  ///
			_tab %9.3f (tmt_mean_`var') _tab  %9.3f (coeff_`var')  _tab _tab ///
			_tab %9.3f (obs_`var') _tab "`star_`var''"  _n

			replace `newCounter' = `newCounter' + 1
		}
		else {
			file write `newHandle' %9.3f (`newCounter') _tab `"`var_legend'"' ///
			_tab %9.3f (tmt_mean_`var') _tab  %9.3f (coeff_`var')  			///
			_tab %9.3f (conf_int_min_`var') _tab %9.3f (conf_int_max_`var')	///
			_tab %9.3f (obs_`var')   _tab "`star_`var''"  _n

			replace `newCounter' = `newCounter' + 1
		}
	}

	file close `newHandle'

/*******************************************************************************

						Create the graph

*******************************************************************************/

	*Read file with results
	insheet using `newTextFile', clear

	*Defining various options to go on the graph option.

	local tmtGroupBars 	""
	local xAxisLabels 	`"xlabel( "'
	local legendLabels	""
	local legendNumbers	""

	forval tmtGroupCount = 1/`graphCount' {

		************
		*Create the bar for this group

		if "`grayscale'" == "" {
			colorPicker `tmtGroupCount' `graphCount'
		}
		else {
			grayPicker `tmtGroupCount' `graphCount'
		}

		local tmtGroupBars `"`tmtGroupBars' (bar mean position if position == `tmtGroupCount', `baroptions' color("`r(color)'") lcolor(black) ) "'

		************
		*Create labels etc. for this group

		local obs 			= obs[`tmtGroupCount']
		local stars 		= star[`tmtGroupCount']
		local legendLabel 	= xlabeled[`tmtGroupCount']

		local xAxisLabels 	`"`xAxisLabels' `tmtGroupCount' "(N = `obs') `stars'" "'
		local legendLabels 	`"`legendLabels' lab(`tmtGroupCount' "`legendLabel'") "'
		local legendNumbers	`"`legendNumbers' `tmtGroupCount'"'
	}

	*Close or complete some strings
	local xAxisLabels `"`xAxisLabels' ,noticks labsize(medsmall)) "'
	local legendOption `"legend(order(`legendNumbers') `legendLabels')"'

	*Create the confidence interval bars

	if `CONFINT_BAR' == 0 {

		local confIntGraph = ""
	}
		else if `CONFINT_BAR' == 1 {
		local confIntGraph = `"(rcap conf_int_max conf_int_min position, lc(gs)) (scatter mean position,  msym(none)  mlabsize(`mlabsize') mlabposition(`mlabposition') mlabcolor(`mlabcolor'))"'
	}

	*Create the bar label
	if `LABEL_BAR' == 0 {
		local barLabel = ""
	}
	else if `LABEL_BAR' == 1 {

		gen label = mean

		if `LABEL_FORMAT' == 1 {
			format label `barlabelformat'
		}
		else if `LABEL_FORMAT' == 0 {
			format label %9.1f
		}

		local barLabel = `"(scatter mean position,  msym(none)  mlab(label) mlabposition(`mlabposition') mlabcolor(`mlabcolor'))"'
	}

	local titleOption `" , xtitle("") ytitle("`e(depvar)'") "'

	if "`save'" != "" {
		local saveOption saving("`save'", replace)
	}

	*******************************************************************************
	*** Generating the graph axis labels for the [yzero] option used..
	*******************************************************************************

	*Calculations needed if yzero used
	if  ("`yzero'" != "" ) {

		**Testing if [yzero] is applicable
		********************************

		** [yzero] is only applicable if all values used in the graph
		* are all negative or all positive. If there is a mix, then
		* the [yzero] option will be ignored

		*Finding the min value for all values used in the graph
		gen row_minvalue = min(mean, conf_int_min, conf_int_max)
		sum row_minvalue
		local min_value `r(min)'

		*Finding the min value for all values used in the graph
		gen row_maxvalue = max(mean , conf_int_max, conf_int_min)
		sum row_maxvalue
		local max_value `r(max)'

		*Locals used for logic below
		local signcheck = ((`max_value' * `min_value') >= 0) 	// dummy local for both signs the same (positive or negative)
		local negative	=  (`max_value' <= 0)				// dummy for max value still negative (including 0)

		**If [yzero] is used and min and max does not have
		* the same sign, then [yzero] is not applicable.

		if (`signcheck' == 0 ) {

		**** [yzero] is NOT applicable and will be ignored
		*************************************************

			noi di "{pstd}{error:WARNING:} Option yzero will be ignored as the graph has values both on the the positve and negative part of the y-axis. This only affects formatting of the graph. See helpfile for more details.{p_end}"
		}
		else {

		**** [yzero] is applicable and will be used
		*****************************************

			*Get max value if only postive values
			if (`negative' == 0) {

				sum row_maxvalue
				local absMax = `max_value'
			}

			*Get absolute min (will convert back below) if only negative values
			else {

				sum row_minvalue
				local absMax = abs(`min_value')
			}

			*Rounded up to the nearest power of ten
			local logAbsMax = ceil(log10(`absMax'))
			local absMax = 10 ^ (`logAbsMax')

			*Generating quarter value for y-axis markers.
			local quarter = (`absMax') / 4

			**Construct the option to be applied to
			* the graph using the values calculated
			if (`negative' == 0)  {

				local yzero_option ylabel(0(`quarter')`absMax')
			}
			else {

				local absMax = `absMax' * (-1) // Convert back to negative
				local yzero_option ylabel(`absMax'(`quarter')0)
			}
		}
	}

	*******************************************************************************
	***Graph generation based on if the option [save] has an export or a save feature.
	*******************************************************************************

	*Store all the options in one local
	local commandline 		`" `tmtGroupBars' `confIntGraph' `barLabel' `titleOption'  `legendOption' `xAxisLabels' title("`basictitle'") `yzero_option' `options'  "'

	*Error message used in both save-option cases below.
	local graphErrorMessage `" Something went wrong while trying to generate the graph. Click {stata di r(cmd) :display graph options } to see what graph options iegraph used. This can help in locating the source of the error in the command. "'

	if `save_export' == 0 {

		*Generate a return local with the code that will be used to generate the graph
		return local cmd `"graph twoway `commandline' `saveOption'"'

		*Generate the graph
		cap graph twoway `commandline' `saveOption'

		*If error, provide error message and then run the code again allowing the program to crash
		if _rc {

			di as error "{pstd}`graphErrorMessage'{p_end}"
            graph twoway `commandline' `saveOption'
		}
	}
	else if `save_export' == 1 {

		*Generate a return local with the code that will be used to generate the graph
		return local cmd `"graph twoway `commandline'"'

		*Generate the graph
		cap graph twoway `commandline'

		*If error, provide error message and then run the code again allowing the program to crash
		if _rc {

			di as error "{pstd}`graphErrorMessage'{p_end}"
            graph twoway `commandline'
		}

		*Export graph to preferred option
		graph export "`save'", replace

	}

	if "`restore'" == "" restore
}

end
	*******************************************
	*******************************************
		******* To pick colors based  *******
		******* on the number of vars *******
	*******************************************
	*******************************************
	cap	program drop	colorPicker
		program define 	colorPicker , rclass

		args groupCount totalNumGroups

		if `totalNumGroups' == 2 {

			if `groupCount' == 1 return local color "215 25 28"
			if `groupCount' == 2 return local color "43 123 182"
		}
		else if `totalNumGroups' == 3 {

			if `groupCount' == 1 return local color "215 25 28"
			if `groupCount' == 2 return local color "255 255 191"
			if `groupCount' == 3 return local color "43 123 182"
		}
		else if `totalNumGroups' == 4 {

			if `groupCount' == 1 return local color "215 25 28"
			if `groupCount' == 2 return local color "255 255 191"
			if `groupCount' == 3 return local color "171 217 233"
			if `groupCount' == 4 return local color "43 123 182"
		}
		else {

			*For five or more colors we repeat the same pattern

			local colorNum = mod(`groupCount', 5)
			if `colorNum' == 1 return local color "215 25 28"
			if `colorNum' == 2 return local color "253 174 93"
			if `colorNum' == 3 return local color "255 255 191"
			if `colorNum' == 4 return local color "171 217 233"
			if `colorNum' == 0 return local color "43 123 182"

		}

	end

	*******************************************
	*******************************************
		******* Grayscale Option *******
		******* Colour Picker    *******
	*******************************************
	*******************************************

	cap	program drop	grayPicker
		program define 	grayPicker , rclass

		args groupCount totalNumGroups

		if `groupCount' == 1 {

			return local color "black"
		}

		else if `groupCount' == 2 & `totalNumGroups' <= 3 {

			return local color "gs14"
		}
		else {

			local grayscale =  round( (`groupCount'-1) * (100 / (`totalNumGroups'-1) ))

			return local color "`grayscale' `grayscale' `grayscale' `grayscale'"
		}

	end

	*******************************************
	*******************************************
		******* Test if valid  *******
		******* dummies 	   *******
	*******************************************
	*******************************************

	cap program drop 	testDums
		program define	testDums

		unab dumlist : `0'

		foreach dumvar of varlist `dumlist' {

			*Test: all values dummies (missing would have been excluded in regression and we keep if e(sample)
			cap assert inlist(`dumvar',0,1)
			if _rc {
				noi display as error "{phang} The variable `dumvar' is not a dummy. Treatment variable needs to be a dummy (0 or 1) variable. {p_end}"
				noi display ""
				error 149
			}
		}

		/*What we are testing for below:
			- We count the number of dummies that each obervation has the value 1 for.
			- The count numbers must either fit the case of diff-in-diff or the case of regression with one dummy for each treatment arms

			Regular regression with one dummy for each treatment arm
			- Some observations don't have 1 for any dummy - omitted control observations
			- No observation has the value 1 in more than one observation - can't be in more than one treatment group
			- No treatment group can have no observation with value 1 for that dummy

			Diff-in-Diff
			- Some observations don't have 1 for any dummy - omitted controls observations in time = 0
			- Some observation must have value 1 for only the treatment dummy - treatment observations in time = 0
			- Some observation must have value 1 for only the time dummy - control observations in time = 1
			- Some observation must have value 1 for in all three of time, treatment and interaction dummy - treatment observations in time = 1

		*/

		*Count how many dummies is 1 for each observation
		tempvar  dum_count
		egen 	`dum_count' = rowtotal(`dumlist')

		*Exactly one dummy is 1, meaning this observation is in one of the treatment arms
		count if `dum_count' == 1
		local dum_count_1 `r(N)'

		*No dummies is 1, meaning this observation is control
		count if `dum_count' == 0
		local dum_count_0 `r(N)'

		*Exactly 3 dummies are three. Only allowed in the exact case of diff-and-diff regressions
		count if `dum_count' == 3
		local dum_count_3 `r(N)'

		*Exactly 2 or more than three is never correct.
		count if `dum_count' == 2 | `dum_count' > 3
		local dum_count_2orgt3 `r(N)'

		*Test that there are at least some treatment observations
		if `dum_count_0' == 0 		noi di as error "{phang} There are no control observations. One category must be omitted and it should be the omitted category in the regression. The omitted category will be considerd the control group. See helpfile for more info. Disable this test by using option ignoredummytest.{p_end}"
		if `dum_count_0' == 0 		error 480

		*Test that there are at least some control observations (this error should be caught by dummies omitted in the regression)
		if `dum_count_1' == 0 		noi di as error "{phang} There are no treatment observations. None of the dummies have observations for which the dummy has the value 1. See helpfile for more info. Disable this test by using option ignoredummytest.{p_end}"
		if `dum_count_1' == 0 		error 480

		*Test if there are any observations that have two or more than three dummies that is 1
		if `dum_count_2orgt3' > 0 	noi di as error "{phang} There is overlap in the treatment dummies. The dummies must be mutually exclusive meaning that no observation has the value 1 in more than one treatment dummy. The exception is when you use a diff-and-diff, but this dummies is not a valid diff and diff. See helpfile for more info. Disable this test by using option ignoredummytest.{p_end}"
		if `dum_count_2orgt3' > 0 	error 480

		*After passing the previous two steps, test if there are cases that are only allowed in diff
		if `dum_count_3' > 0 {

			*Diff-and-diff must have exactly 3 dummies
			if `:list sizeof dumlist' != 3 	noi di as error "{phang} There is overlap in the treatment dummies. The dummies must be mutually exclusive meaning that no observation has the value 1 in more than one treatment dummy. The exception is when you use a diff-and-diff, but this dummies is not a valid diff and diff. See helpfile for more info. Disable this test by using option ignoredummytest.{p_end}"
			if `:list sizeof dumlist' != 3 	error 480

			* Test if valid diff-diff
			testDumsDD `dum_count' `dumlist'
		}

	end

	cap program drop 	testDumsDD
		program define	testDumsDD

		local dum_count `1'

		**Test that for only two of three dummies there are observations
		* that has only that dummy. I.e. the two that is not the
		* interaction. If the interaction is 1, all three shluld be 1.

		*Count how many dummies the condition is above applies to
		local counter 0

		*Loop over all dummies
		forvalues i = 2/4 {

			*Test the number
			count if ``i'' == 1 & `dum_count' == 1
			if `r(N)' > 0 local ++counter

		}
		*Count that exactly two dummies fullfilled the condition
		if `counter' != 2	noi di as error "{phang} There is overlap in the treatment dummies. The dummies must be mutually exclusive meaning that no observation has the value 1 in more than one treatment dummy. The exception is when you use a diff-and-diff, but this dummies is not a valid diff and diff. See helpfile for more info. Disable this test by using option ignoredummytest.{p_end}""
		if `counter' != 2	error 480

	end

	* Test inputs for label
	cap prog drop sizename
 		prog def sizename, rclass

		args name

		capture findfile gsize-`name'.style

		if ( _rc == 601 ) {

			noi di "{phang} WARNING: Option mlabsize() was incorrectly specified. Only {help textsizestyle} values are accepted. Default size used.{p_end}"
			return local 	LABEL_SIZE 	0
		}

	end

	cap prog drop colorname
		prog def colorname, rclass

		args name

		capture findfile color-`name'.style

		if ( _rc == 601 ) {

			noi di "{phang} WARNING: Option mlabcolor() was incorrectly specified. Only named colors in {help colorstyle} are accepted. Default color used.{p_end}"
			return local 	LABEL_COL 	0
		}

	end

	cap prog drop clockname
		prog def clockname, rclass

		args name

		capture findfile clockdir-`name'.style

		if ( _rc == 601 ) {

			noi di "{phang} WARNING: Option mlabposition() was incorrectly specified. Only {help clockposstyle} values are accepted. Default position used.{p_end}"
			return local 	LABEL_POS 	0
		}

	end


Update WDI importer to cache partial results.

* 2016 World Develoment Indicators
* http://data.worldbank.org/

local PREFIX "wdi"
local YEARVAR "year"
local COUNTRYVAR "countrycode"
local MERGEWITH "WDI"
local MERGEUSING "Alpha"

tempfile merge
prep_mergefile `MERGEWITH' `MERGEUSING' `merge'

* If the file source file doesn't already exist then download and create it.
capture use "source/`PREFIX'.dta", clear
if _rc!=0 {
  noisily display "Importing `PREFIX' from web."
  * set timeout1 360
  * set timeout2 1540
  * Make sure you are using the latest wbopendata update, it will save you headache.
  ssc install wbopendata
  tempfile wdi
  save `wdi', replace
  * Topic 18 doesn't seem to be returning
  foreach x of numlist 1/17 19/21 {
    capture use "source/`PREFIX'`x'.dta"
    if _rc!=0 {
      wbopendata, language(en - English) topics(`x') clear long
      save "source/`PREFIX'`x'.dta"
    }
    if `x' != 1 {
      merge 1:1 countryname year using `wdi', nogenerate
      }
    save `wdi', replace
  }
  compress
  save "source/`PREFIX'.dta"

  * Cleanup redundant cache files
  foreach x of numlist 1/17 19/21 {
    capture rm "source/`PREFIX'`x'.dta"
  }

}

* Fixes:
* Recent WDI changes have dropped the coutnrycode for Kosovo
replace countrycode = "KSV" if countryname == "Kosovo" & countrycode == ""

prefix `PREFIX'

merge_ids `PREFIX' `YEARVAR' `COUNTRYVAR' `MERGEUSING' `merge'

* Drop aggregates
drop if UCINumeric >= 5000

* Merge with the dataset
merge_with_master

* 2015 World Develoment Indicators
* http://data.worldbank.org/

local PREFIX "wdi"
local YEARVAR "year"
local COUNTRYVAR "countrycode"
local MERGEWITH "WDI"
local MERGEUSING "Alpha"

tempfile merge
prep_mergefile `MERGEWITH' `MERGEUSING' `merge'

* If the file source file doesn't already exist then download and create it.
capture confirm file "source/`PREFIX'.dta"
if _rc!=0 {
  noisily display "Importing `PREFIX' from web."
  set timeout1 360
  set timeout2 1540
  capture wbopendata, language(en - English) topics(1) clear long
  if _rc!=0 {
    ssc install wbopendata
    wbopendata, language(en - English) topics(1) clear long
  }
  tempfile wdi
  save `wdi', replace
  foreach x of numlist 2/21 {
    wbopendata, language(en - English) topics(`x') clear long
    compress
    merge 1:1 countryname year using `wdi', nogenerate
    save `wdi', replace
  }
  save "source/`PREFIX'.dta"
}
else {
  use "source/`PREFIX'.dta", clear
}

* Fixes:
* Recent WDI changes have dropped the coutnrycode for Kosovo
replace countrycode = "KSV" if countryname == "Kosovo" & countrycode == ""

prefix `PREFIX'

merge_ids `PREFIX' `YEARVAR' `COUNTRYVAR' `MERGEUSING' `merge'

* Drop aggregates
drop if UCINumeric >= 5000

* Merge with the dataset
merge_with_master


testing more parallelism.

testing more parallelism.

#!/usr/bin/env sh
OUT_PATH=$(dirname $2)
DEPS=${OUT_PATH}/test0
for i in $(seq 1 10); do
    DEPS="${DEPS} ${OUT_PATH}/test-sub${i}.a"
done
./redo-ifchange ${DEPS}
if [ -f flags ]; then
    ./redo-ifchange flags
else
    ./redo-ifcreate flags
fi
echo $0 $1 $2 > $3

#!/usr/bin/env sh
OUT_PATH=$(dirname $2)
./redo-ifchange test0 ${OUT_PATH}/test-sub1.a ${OUT_PATH}/test-sub2.a ${OUT_PATH}/test-sub3.a ${OUT_PATH}/test-sub4.a ${OUT_PATH}/test-sub5.a
if [ -f flags ]; then
    ./redo-ifchange flags
else
    ./redo-ifcreate flags
fi
echo $0 $1 $2 > $3


ieddtab : typo in name

ieddtab : typo in name

{smcl}
{* 19 Oct 2018}{...}
{hline}
help for {hi:ieddtab}
{hline}

{title:Title}

{phang2}{cmdab:ieddtab} {hline 2} This command runs a Diff-in-Diff regression and displays the baseline values, the two 1st differences and the 2nd difference.

{phang2}For a more descriptive discussion on the intended usage and work flow of this
command please see the {browse "https://dimewiki.worldbank.org/wiki/ieddtab":DIME Wiki}.

{title:Syntax}

{phang2} {cmdab:ieddtab} {it:varlist},
	{cmdab:t:ime(}{it:varname}{cmd:)} {cmdab:treat:ment(}{it:varname}{cmd:)}
	[
		{cmdab:covar:iates(}{it:varlist}{cmd:)} {cmdab:starl:evels(}{it:numlist}{cmd:)}
		{cmdab:err:ortype(}{it:string}{cmd:)} {cmdab:rowl:abtype(}{it:string}{cmd:)}
		{cmdab:rowlabtext(}{it:label_string}{cmd:)} {cmdab:format(}{it:{help format:%fmt}}{cmd:)}
		{cmdab:replace} {cmdab:savet:ex(}{it:filepath}{cmd:)} {cmdab:onerow}
		{cmdab:nonotes} {cmdab:addn:otes(}{it:string}{cmd:)}  {cmdab:texdoc:ument}
		{cmdab:texc:aption(}{it:string}{cmd:)} {cmdab:texl:abel(}{it:string}{cmd:)}
		{cmdab:texn:otewidth(}{it:numlist}{cmd:)} {cmdab:texvspace(}{it:string}{cmd:)}
	]

{marker opts}{...}
{synoptset 24}{...}
{synopthdr:options}
{synoptline}
{pstd}{it:Required options:}{p_end}
{synopt :{cmdab:t:ime(}{it:varname}{cmd:)}}Time dummy to use in diff-in-diff regression{p_end}
{synopt :{cmdab:treat:ment(}{it:varname}{cmd:)}}Treatment dummy to use in diff-in-diff regression{p_end}

{pstd}{it:Statistics options:}{p_end}
{synopt :{cmdab:covar:iates(}{it:varlist}{cmd:)}}Covariates to use in diff-in-diff regression{p_end}
{synopt :{cmdab:vce:(}{it:{help vce_option:vce_types}}{cmd:)}}Options for variance estimation. {hi:Robust}, {hi:cluster} {it:clustervar} or {hi:bootstrap}{p_end}
{synopt :{cmdab:starl:evels(}{it:numlist}{cmd:)}}Significance levels used for significance stars, default values are .1, .05 and .01{p_end}
{synopt :{cmdab:err:ortype(}{it:string}{cmd:)}}Type of errors to display, default is standard errors.{p_end}

{pstd}{it:Output options:}{p_end}
{synopt :{cmdab:rowl:abtype(}{it:string}{cmd:)}}Indicate what to use as row titles, default is variable name.{p_end}
{synopt :{cmdab:rowlabtext(}{it:label_string}{cmd:)}}Manually enter the row titles using label strings (see below).{p_end}
{synopt :{cmdab:nonote}}Disable that the automatically generated note is displayed below the table.{p_end}
{synopt :{cmdab:addn:otes(}{it:string}{cmd:)}}Manually add a note to be displayed below the regression result table.{p_end}
{synopt :{cmdab:onerow}}Display the number of observations on one row at the last row of the table.{p_end}
{synopt :{cmdab:format(}{it:{help format:%fmt}}{cmd:)}}Set the rounding format of the calculated statistics in the table.{p_end}
{synopt :{cmdab:replace}}Replace the file on disk if it already exist. Has no effect if no option with file path is used.{p_end}

{pstd}{it:LaTeX options:}{p_end}
{synopt :{cmdab:savet:ex(}{it:filepath}{cmd:)}}Generate a LaTeX table of the result and save to the location of the file path.{p_end}
{synopt :{cmdab:texdoc:ument}}Creates a stand-alone TeX document.{p_end}
{synopt :{cmdab:texc:aption(}{it:string}{cmd:)}}Specify table's caption on TeX file.{p_end}
{synopt :{cmdab:texl:abel(}{it:string}{cmd:)}}Specify table's label, used for meta-reference across TeX file.{p_end}
{synopt :{cmdab:texn:otewidth(}{it:numlist}{cmd:)}}Manually enter the width of the note on the TeX file.{p_end}
{synopt :{cmd:texvspace(}{it:string}{cmd:)}}Manually set size of the line space between two rows on TeX output.{p_end}
{synoptline}

{marker desc}
{title:Description}

{pstd}{cmdab:ieddtab} is a command that makes it easy to run and display results of differences-in-differences (diff-in-diff) regressions. The table that presents the results from the diff-in-diff regression also presents the mean when the variable in {inp:time()} is 0 (i.e. baseline) for the two groups defined by the variable {inp:treatment()} is 0 and 1 (i.e. control and treatment), and the table also presents the coefficient of the first difference regression in control and treatment.{p_end}

{pstd}The sample for each row in the table is defined by the sample included in the second difference regression shown below, where {it:outcome_var} is a variable the varlist (one per row) for {inp:ieddtab}, {inp:`interaction'} is the interaction of the dummy listed in {inp:time()} and the dummy listed in {inp:treatment()}, and where {inp:`covariates'} is the list of covariates included in {inp:covariates()} if any. This means that any observation that has any missing value in either of the two dummies or in any of the covariates will be omitted from all statistics presented in the table. The coefficient presented in the table for the diff-in-diff regression is the interaction of the time and treatment variable.{p_end}

{pstd}{inp:tempvar} {it:interaction}{p_end}
{pstd}{inp:generate `interaction' = `time' * `treatment'}{p_end}
{pstd}{inp:regress} {it:outcome_var} {inp:`time' `treatment' `interaction' `covariates'}{p_end}

{pstd}The baseline means are then calculated using the following code where the first line is control and the second line is treatment, and the variable {inp:regsample} is dummy indicating if the observation was included in the second difference regression.{p_end}

{pstd}{inp:mean} {it:outcome_var} {inp:if `treatment' == 0 & `time' == 0 & regsample == 1}{p_end}
{pstd}{inp:mean} {it:outcome_var} {inp:if `treatment' == 1 & `time' == 0 & regsample == 1}{p_end}

{pstd}The first difference coefficients are then calculated using the following code where the first line is control and the second line is treatment. The coefficient displayed in the table is the coefficient of the variable `time' which is the variable listed in {inp:t()}.{p_end}

{pstd}{inp:regress} {it:outcome_var} {inp: `time' `covariates' if `treatment' == 0 & regsample == 1}{p_end}
{pstd}{inp:regress} {it:outcome_var} {inp: `time' `covariates' if `treatment' == 1 & regsample == 1}{p_end}

{marker optslong}
{title:Options}

{pstd}{it:{ul:{hi:Required options:}}}{p_end}
{phang}{cmdab:t(}{it:varname}{cmd:)} indicates which variable should be used as the time dummy to use in diff-in-diff regression. This must be a dummy variable, i.e. only have 0, 1 or missing as values, where 0 is baseline and 1 is follow-up.{p_end}

{phang}{cmdab:treatment(}{it:varname}{cmd:)} indicates which variable should be used as the treatment dummy to use in diff-in-diff regression. This must be a dummy variable, i.e. only have 0, 1 or missing as values.{p_end}

{pstd}{it:{ul:{hi:Statistics options:}}}{p_end}
{phang}{cmdab:covar:iates(}{it:varlist}{cmd:)} lists the variables that should be included as covariates (independent variables not reported in the table) in the two first difference regressions and the second diffrence regression. Unless the option {cmdab:nonotes} is used a list of covariate variables is included below the table.{p_end}

{phang}{cmdab:vce:(}{it:{help vce_option:vce_types}{cmd:)}} sets the type of variance estimator to be used in all regressions for this
command. See {help vce_option:vce_types} for more details. The only vce types allowed in this command are {hi:robust}, {hi:cluster} {it:clustervar} or {hi:bootstrap}.
Option {hi:robust} only applied to first and second difference estimators, not to baseline means.{p_end}

{phang}{cmdab:starl:evels(}{it:numlist}{cmd:)} sets the significance levels used for significance stars. Exactly three values must be listed if this option is used, all three values must be descending order, and must be between 0 and 1. The default values are .1, .05 and .01{p_end}

{phang}{cmdab:err:ortype(}{it:string}{cmd:)} sets the type of error to display. Allowed values for this iption is {inp:se} for standard errors, {inp:sd} for standard deviation and {inp:errhide} for not displaying any errors in the table. The default is to display standard errors.{p_end}

{pstd}{it:{ul:{hi:Output options:}}}{p_end}
{phang}{cmdab:rowl:abtype(}{it:string}{cmd:)} indicates what to use as row titles. The allowed values are {inp:varname} using the variable name as row titles, {inp:varlab} using the variable labels as row titles (varname will still be used if the variable does not have a variable label). The default is to use the variable name.{p_end}

{phang}{cmdab:rowlabtext(}{it:label_string}{cmd:)} manually specifies the row titles using label strings. A label string is a list of variable names followed by the row title for that variable separated by "@@". For example {it:varA Row title variable A @@ varB Row title variable B}, where {it:varA} and {it:varB} are outcome variables used in this command. For variable not listed in {cmdab:rowlabtext()} row titles will be determined by the input value or default value in {cmdab:rowl:abtype()}.{p_end}

{phang}{cmdab:nonotes} disable that the command automatically generates and displays a note below the table describing the output in the table. The note includes description on how number of calculations are calculated, the significance levels used for stars and which covariates were uses if any were used.{p_end}

{phang}{cmdab:addn:otes(}{it:string}{cmd:)} is used to manually add a note to be displayed below the regression result table. This note is put before the automatically generated note, unless option {cmdab:nonotes} is specified, in which case only the manually added note is displayed.{p_end}

{phang}{cmdab:onerow} indicated that the number of observations should be displayed on one row at the last row of the table instead on each row. This requires that the number of observations are the same across all rows for each column.{p_end}

{phang}{cmdab:format(}{it:{help format:%fmt}}{cmd:)} sets the number formatting/rounding rule for all calculated statistics in the table, that is all numbers in the table apart from the number of observations. Only valid {help format:Stata number formats} are allowed. The default is {it:%9.2f}.{p_end}

{phang}{cmdab:replace} if an option is used that output a file and a file with that name already exists at that location, then Stata will throw an error unless this option is used. If this option is used then Stata overwrites the file on disk with the new output. This option has no effect if no option with file path is used.{p_end}

{pstd}{it:{ul:{hi:LaTeX options:}}}{p_end}
{phang}{cmdab:savet:ex(}{it:filepath}{cmd:)} saves the table in TeX format to the location of the file path.{p_end}

{phang}{cmdab:texdoc:ument} creates a stand-alone TeX document that can be readily compiled, without the need to import it to a different file.
 As default, {cmd:savetex()} creates a fragmented TeX file consisting only of a tabular environment.

{phang}{cmdab:texc:aption(}{it:string}{cmd:)} writes table's caption in TeX file. Can only be used with option texdocument. {p_end}

{phang}{cmdab:texl:abel(}{it:string}{cmd:)} specifies table's label, used for meta-reference across TeX file. Can only be used with option texdocument.{p_end}

{phang}{cmdab:texn:otewidth(}{it:numlist}{cmd:)} manually adjusts the width of the note to fit the size of the table.
The note width is a multiple of text width. If not specified, default is one, which makes the table width equal to text width.{p_end}

{phang}{cmd:texvspace(}{it:string}{cmd:)} sets the size of the line space between two variable rows. {it:string} must consist of a numeric value
and one of the following units: "cm", "mm", "pt", "in", "ex" or "em". Note that the resulting line space displayed will be equal to the
specified value minus the height of one line of text. Default is "3ex". For more information on units,
{browse "https://en.wikibooks.org/wiki/LaTeX/Lengths":check LaTeX lengths manual}. {p_end}

{marker optslong}
{title:Examples}

{pstd}All the examples below can be run on the Stata's built in census data set, by first running this code:{p_end}

{pstd}*Open the built in data set{p_end}
{pstd}{inp:sysuse census}{p_end}

{pstd}*Calculate rates from absolute numbers{p_end}
{pstd}{inp:replace death = 100 * death / pop}{p_end}
{pstd}{inp:replace marriage = 100 * marriage / pop}{p_end}
{pstd}{inp:replace divorce = 100 * divorce / pop}{p_end}

{pstd}*Randomly assign time and treatment dummies{p_end}
{pstd}{inp:gen t	= (runiform()<.5)}{p_end}
{pstd}{inp:gen treatment = (runiform()<.5)}{p_end}

{pstd} {hi:Example 1.}

{pstd} {inp:ieddtab} {it:death marriage divorce} , {inp:t(}{it:time}{inp:)} {inp:treatment(}{it:treatment}{inp:)}

{pstd}This is the most basic way to run this command with three variables. This will output a table with the baseline means for treatment = 0 and treatment = 1, the first difference regression coefficient for treatment = 0 and treatment = 1 as well as the 2nd difference regression coefficient for treatment = 0 and treatment = 1.

{pstd} {hi:Example 2.}

{pstd} {inp:ieddtab} {it:death marriage divorce} ,  {inp:t(}{it:time}{inp:)} {inp:treatment(}{it:treatment}{inp:)}  {inp:rowlabtext(}{it:"death Death Rate @@ divorce Divorce Rate"}{inp:)} {inp:rowlabtype(}{it:"varlab"}{inp:)}

{pstd}The table generated by example 2 will have the same statistics as in example 1 but the row title for the variables death and divorce are entered manually and the row title for marriage will be its variable label instead of its variable name.

{pstd} {hi:Example 3.}

{pstd} {inp:ieddtab} {it:death marriage divorce} ,  {inp:t(}{it:time}{inp:)} {inp:treatment(}{it:treatment}{inp:)}  {inp:rowlabtype(}{it:"varlab"}{inp:)} {inp:savetex(}{it:"DID table.tex"}{inp:)} {inp:replace}

{pstd}The table will be saved in the current directory under the name "DID table.tex". It will will have the same statistics as in examples 1 and 2, and the row titles will be its variable labels.

{title:Acknowledgements}

{phang}This command was initally suggested by Esteban J. Quinones, University of Wisconsin-Madison{p_end}

{phang}We would like to acknowledge the help in testing and proofreading we received in relation to this command and help file from (in alphabetic order):{p_end}
{pmore}Benjamin Daniels{break}Jonas Guthoff{break}Michael Orevba{break}Matteo Ruzzante{break}Sakina Shibuya

{title:Author}

{phang}All commands in ietoolkit is developed by DIME Analytics at DECIE, The World Bank's unit for Development Impact Evaluations.{p_end}

{phang}Main author: Kristoffer Bjarkefur, Luiza Cardoso De Andrade, DIME Analytics, The World Bank Group{p_end}

{phang}Please send bug-reports, suggestions and requests for clarifications
		 writing "ietoolkit ieddtab" in the subject line to:{break}
		 dimeanalytics@worldbank.org{p_end}

{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"}{p_end}

{smcl}
{* 19 Oct 2018}{...}
{hline}
help for {hi:ieddtab}
{hline}

{title:Title}

{phang2}{cmdab:ieddtab} {hline 2} This command runs a Diff-in-Diff regression and displays the baseline values, the two 1st differences and the 2nd difference.

{phang2}For a more descriptive discussion on the intended usage and work flow of this
command please see the {browse "https://dimewiki.worldbank.org/wiki/ieddtab":DIME Wiki}.

{title:Syntax}

{phang2} {cmdab:ieddtab} {it:varlist},
	{cmdab:t:ime(}{it:varname}{cmd:)} {cmdab:treat:ment(}{it:varname}{cmd:)}
	[
		{cmdab:covar:iates(}{it:varlist}{cmd:)} {cmdab:starl:evels(}{it:numlist}{cmd:)}
		{cmdab:err:ortype(}{it:string}{cmd:)} {cmdab:rowl:abtype(}{it:string}{cmd:)}
		{cmdab:rowlabtext(}{it:label_string}{cmd:)} {cmdab:format(}{it:{help format:%fmt}}{cmd:)}
		{cmdab:replace} {cmdab:savet:ex(}{it:filepath}{cmd:)} {cmdab:onerow}
		{cmdab:nonotes} {cmdab:addn:otes(}{it:string}{cmd:)}  {cmdab:texdoc:ument}
		{cmdab:texc:aption(}{it:string}{cmd:)} {cmdab:texl:abel(}{it:string}{cmd:)}
		{cmdab:texn:otewidth(}{it:numlist}{cmd:)} {cmdab:texvspace(}{it:string}{cmd:)}
	]

{marker opts}{...}
{synoptset 24}{...}
{synopthdr:options}
{synoptline}
{pstd}{it:Required options:}{p_end}
{synopt :{cmdab:t:ime(}{it:varname}{cmd:)}}Time dummy to use in diff-in-diff regression{p_end}
{synopt :{cmdab:treat:ment(}{it:varname}{cmd:)}}Treatment dummy to use in diff-in-diff regression{p_end}

{pstd}{it:Statistics options:}{p_end}
{synopt :{cmdab:covar:iates(}{it:varlist}{cmd:)}}Covariates to use in diff-in-diff regression{p_end}
{synopt :{cmdab:vce:(}{it:{help vce_option:vce_types}}{cmd:)}}Options for variance estimation. {hi:Robust}, {hi:cluster} {it:clustervar} or {hi:bootstrap}{p_end}
{synopt :{cmdab:starl:evels(}{it:numlist}{cmd:)}}Significance levels used for significance stars, default values are .1, .05 and .01{p_end}
{synopt :{cmdab:err:ortype(}{it:string}{cmd:)}}Type of errors to display, default is standard errors.{p_end}

{pstd}{it:Output options:}{p_end}
{synopt :{cmdab:rowl:abtype(}{it:string}{cmd:)}}Indicate what to use as row titles, default is variable name.{p_end}
{synopt :{cmdab:rowlabtext(}{it:label_string}{cmd:)}}Manually enter the row titles using label strings (see below).{p_end}
{synopt :{cmdab:nonote}}Disable that the automatically generated note is displayed below the table.{p_end}
{synopt :{cmdab:addn:otes(}{it:string}{cmd:)}}Manually add a note to be displayed below the regression result table.{p_end}
{synopt :{cmdab:onerow}}Display the number of observations on one row at the last row of the table.{p_end}
{synopt :{cmdab:format(}{it:{help format:%fmt}}{cmd:)}}Set the rounding format of the calculated statistics in the table.{p_end}
{synopt :{cmdab:replace}}Replace the file on disk if it already exist. Has no effect if no option with file path is used.{p_end}

{pstd}{it:LaTeX options:}{p_end}
{synopt :{cmdab:savet:ex(}{it:filepath}{cmd:)}}Generate a LaTeX table of the result and save to the location of the file path.{p_end}
{synopt :{cmdab:texdoc:ument}}Creates a stand-alone TeX document.{p_end}
{synopt :{cmdab:texc:aption(}{it:string}{cmd:)}}Specify table's caption on TeX file.{p_end}
{synopt :{cmdab:texl:abel(}{it:string}{cmd:)}}Specify table's label, used for meta-reference across TeX file.{p_end}
{synopt :{cmdab:texn:otewidth(}{it:numlist}{cmd:)}}Manually enter the width of the note on the TeX file.{p_end}
{synopt :{cmd:texvspace(}{it:string}{cmd:)}}Manually set size of the line space between two rows on TeX output.{p_end}
{synoptline}

{marker desc}
{title:Description}

{pstd}{cmdab:ieddtab} is a command that makes it easy to run and display results of differences-in-differences (diff-in-diff) regressions. The table that presents the results from the diff-in-diff regression also presents the mean when the variable in {inp:time()} is 0 (i.e. baseline) for the two groups defined by the variable {inp:treatment()} is 0 and 1 (i.e. control and treatment), and the table also presents the coefficient of the first difference regression in control and treatment.{p_end}

{pstd}The sample for each row in the table is defined by the sample included in the second difference regression shown below, where {it:outcome_var} is a variable the varlist (one per row) for {inp:ieddtab}, {inp:`interaction'} is the interaction of the dummy listed in {inp:time()} and the dummy listed in {inp:treatment()}, and where {inp:`covariates'} is the list of covariates included in {inp:covariates()} if any. This means that any observation that has any missing value in either of the two dummies or in any of the covariates will be omitted from all statistics presented in the table. The coefficient presented in the table for the diff-in-diff regression is the interaction of the time and treatment variable.{p_end}

{pstd}{inp:tempvar} {it:interaction}{p_end}
{pstd}{inp:generate `interaction' = `time' * `treatment'}{p_end}
{pstd}{inp:regress} {it:outcome_var} {inp:`time' `treatment' `interaction' `covariates'}{p_end}

{pstd}The baseline means are then calculated using the following code where the first line is control and the second line is treatment, and the variable {inp:regsample} is dummy indicating if the observation was included in the second difference regression.{p_end}

{pstd}{inp:mean} {it:outcome_var} {inp:if `treatment' == 0 & `time' == 0 & regsample == 1}{p_end}
{pstd}{inp:mean} {it:outcome_var} {inp:if `treatment' == 1 & `time' == 0 & regsample == 1}{p_end}

{pstd}The first difference coefficients are then calculated using the following code where the first line is control and the second line is treatment. The coefficient displayed in the table is the coefficient of the variable `time' which is the variable listed in {inp:t()}.{p_end}

{pstd}{inp:regress} {it:outcome_var} {inp: `time' `covariates' if `treatment' == 0 & regsample == 1}{p_end}
{pstd}{inp:regress} {it:outcome_var} {inp: `time' `covariates' if `treatment' == 1 & regsample == 1}{p_end}

{marker optslong}
{title:Options}

{pstd}{it:{ul:{hi:Required options:}}}{p_end}
{phang}{cmdab:t(}{it:varname}{cmd:)} indicates which variable should be used as the time dummy to use in diff-in-diff regression. This must be a dummy variable, i.e. only have 0, 1 or missing as values, where 0 is baseline and 1 is follow-up.{p_end}

{phang}{cmdab:treatment(}{it:varname}{cmd:)} indicates which variable should be used as the treatment dummy to use in diff-in-diff regression. This must be a dummy variable, i.e. only have 0, 1 or missing as values.{p_end}

{pstd}{it:{ul:{hi:Statistics options:}}}{p_end}
{phang}{cmdab:covar:iates(}{it:varlist}{cmd:)} lists the variables that should be included as covariates (independent variables not reported in the table) in the two first difference regressions and the second diffrence regression. Unless the option {cmdab:nonotes} is used a list of covariate variables is included below the table.{p_end}

{phang}{cmdab:vce:(}{it:{help vce_option:vce_types}{cmd:)}} sets the type of variance estimator to be used in all regressions for this
command. See {help vce_option:vce_types} for more details. The only vce types allowed in this command are {hi:robust}, {hi:cluster} {it:clustervar} or {hi:bootstrap}.
Option {hi:robust} only applied to first and second difference estimators, not to baseline means.{p_end}

{phang}{cmdab:starl:evels(}{it:numlist}{cmd:)} sets the significance levels used for significance stars. Exactly three values must be listed if this option is used, all three values must be descending order, and must be between 0 and 1. The default values are .1, .05 and .01{p_end}

{phang}{cmdab:err:ortype(}{it:string}{cmd:)} sets the type of error to display. Allowed values for this iption is {inp:se} for standard errors, {inp:sd} for standard deviation and {inp:errhide} for not displaying any errors in the table. The default is to display standard errors.{p_end}

{pstd}{it:{ul:{hi:Output options:}}}{p_end}
{phang}{cmdab:rowl:abtype(}{it:string}{cmd:)} indicates what to use as row titles. The allowed values are {inp:varname} using the variable name as row titles, {inp:varlab} using the variable labels as row titles (varname will still be used if the variable does not have a variable label). The default is to use the variable name.{p_end}

{phang}{cmdab:rowlabtext(}{it:label_string}{cmd:)} manually specifies the row titles using label strings. A label string is a list of variable names followed by the row title for that variable separated by "@@". For example {it:varA Row title variable A @@ varB Row title variable B}, where {it:varA} and {it:varB} are outcome variables used in this command. For variable not listed in {cmdab:rowlabtext()} row titles will be determined by the input value or default value in {cmdab:rowl:abtype()}.{p_end}

{phang}{cmdab:nonotes} disable that the command automatically generates and displays a note below the table describing the output in the table. The note includes description on how number of calculations are calculated, the significance levels used for stars and which covariates were uses if any were used.{p_end}

{phang}{cmdab:addn:otes(}{it:string}{cmd:)} is used to manually add a note to be displayed below the regression result table. This note is put before the automatically generated note, unless option {cmdab:nonotes} is specified, in which case only the manually added note is displayed.{p_end}

{phang}{cmdab:onerow} indicated that the number of observations should be displayed on one row at the last row of the table instead on each row. This requires that the number of observations are the same across all rows for each column.{p_end}

{phang}{cmdab:format(}{it:{help format:%fmt}}{cmd:)} sets the number formatting/rounding rule for all calculated statistics in the table, that is all numbers in the table apart from the number of observations. Only valid {help format:Stata number formats} are allowed. The default is {it:%9.2f}.{p_end}

{phang}{cmdab:replace} if an option is used that output a file and a file with that name already exists at that location, then Stata will throw an error unless this option is used. If this option is used then Stata overwrites the file on disk with the new output. This option has no effect if no option with file path is used.{p_end}

{pstd}{it:{ul:{hi:LaTeX options:}}}{p_end}
{phang}{cmdab:savet:ex(}{it:filepath}{cmd:)} saves the table in TeX format to the location of the file path.{p_end}

{phang}{cmdab:texdoc:ument} creates a stand-alone TeX document that can be readily compiled, without the need to import it to a different file.
 As default, {cmd:savetex()} creates a fragmented TeX file consisting only of a tabular environment.

{phang}{cmdab:texc:aption(}{it:string}{cmd:)} writes table's caption in TeX file. Can only be used with option texdocument. {p_end}

{phang}{cmdab:texl:abel(}{it:string}{cmd:)} specifies table's label, used for meta-reference across TeX file. Can only be used with option texdocument.{p_end}

{phang}{cmdab:texn:otewidth(}{it:numlist}{cmd:)} manually adjusts the width of the note to fit the size of the table.
The note width is a multiple of text width. If not specified, default is one, which makes the table width equal to text width.{p_end}

{phang}{cmd:texvspace(}{it:string}{cmd:)} sets the size of the line space between two variable rows. {it:string} must consist of a numeric value
and one of the following units: "cm", "mm", "pt", "in", "ex" or "em". Note that the resulting line space displayed will be equal to the
specified value minus the height of one line of text. Default is "3ex". For more information on units,
{browse "https://en.wikibooks.org/wiki/LaTeX/Lengths":check LaTeX lengths manual}. {p_end}

{marker optslong}
{title:Examples}

{pstd}All the examples below can be run on the Stata's built in census data set, by first running this code:{p_end}

{pstd}*Open the built in data set{p_end}
{pstd}{inp:sysuse census}{p_end}

{pstd}*Calculate rates from absolute numbers{p_end}
{pstd}{inp:replace death = 100 * death / pop}{p_end}
{pstd}{inp:replace marriage = 100 * marriage / pop}{p_end}
{pstd}{inp:replace divorce = 100 * divorce / pop}{p_end}

{pstd}*Randomly assign time and treatment dummies{p_end}
{pstd}{inp:gen t	= (runiform()<.5)}{p_end}
{pstd}{inp:gen treatment = (runiform()<.5)}{p_end}

{pstd} {hi:Example 1.}

{pstd} {inp:ieddtab} {it:death marriage divorce} , {inp:t(}{it:time}{inp:)} {inp:treatment(}{it:treatment}{inp:)}

{pstd}This is the most basic way to run this command with three variables. This will output a table with the baseline means for treatment = 0 and treatment = 1, the first difference regression coefficient for treatment = 0 and treatment = 1 as well as the 2nd difference regression coefficient for treatment = 0 and treatment = 1.

{pstd} {hi:Example 2.}

{pstd} {inp:ieddtab} {it:death marriage divorce} ,  {inp:t(}{it:time}{inp:)} {inp:treatment(}{it:treatment}{inp:)}  {inp:rowlabtext(}{it:"death Death Rate @@ divorce Divorce Rate"}{inp:)} {inp:rowlabtype(}{it:"varlab"}{inp:)}

{pstd}The table generated by example 2 will have the same statistics as in example 1 but the row title for the variables death and divorce are entered manually and the row title for marriage will be its variable label instead of its variable name.

{pstd} {hi:Example 3.}

{pstd} {inp:ieddtab} {it:death marriage divorce} ,  {inp:t(}{it:time}{inp:)} {inp:treatment(}{it:treatment}{inp:)}  {inp:rowlabtype(}{it:"varlab"}{inp:)} {inp:savetex(}{it:"DID table.tex"}{inp:)} {inp:replace}

{pstd}The table will be saved in the current directory under the name "DID table.tex". It will will have the same statistics as in examples 1 and 2, and the row titles will be its variable labels.

{title:Acknowledgements}

{phang}This command was initally suggested by Esteban J. Quinnones, University of Wisconsin-Madison{p_end}

{phang}We would like to acknowledge the help in testing and proofreading we received in relation to this command and help file from (in alphabetic order):{p_end}
{pmore}Benjamin Daniels{break}Jonas Guthoff{break}Michael Orevba{break}Matteo Ruzzante{break}Sakina Shibuya

{title:Author}

{phang}All commands in ietoolkit is developed by DIME Analytics at DECIE, The World Bank's unit for Development Impact Evaluations.{p_end}

{phang}Main author: Kristoffer Bjarkefur, Luiza Cardoso De Andrade, DIME Analytics, The World Bank Group{p_end}

{phang}Please send bug-reports, suggestions and requests for clarifications
		 writing "ietoolkit ieddtab" in the subject line to:{break}
		 dimeanalytics@worldbank.org{p_end}

{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"}{p_end}


ieimpgraph run file lightenign seminar

ieimpgraph run file lightenign seminar

Prepare the run file for the presentation in the lightening seminar

	*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 testOuput "$ietoolkit/test/ieimpgraphOutput"

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

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

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

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

	*Run the impact regression
	reg price  dummy
	*Create the graph
	ieimpgraph dummy, title("Treatment effect on price") save("$testOuput/Graph1.gph")

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

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

	*Run the impact regression
	reg price  d_2 d_3 d_4 d_5 weight length gear_ratio
	*Create the graph
	ieimpgraph d_2 d_3 d_4 d_5, title("Treatment effect on price") save("$testOuput/Graph2.gph")

		version 12.0
		set more off
		pause on

		cd "C:\Users\wb503680\Box Sync\DIME WOrk\GitFolder\ietoolkit\test"

		do "C:\Users\wb503680\Box Sync\DIME WOrk\GitFolder\ietoolkit\ieimpgraph2.do"

		sysuse auto, replace
		gen weight2 = 1 if weight >= 3019.5
		replace weight2 = 0 if weight2 == .

		reg price  weight2
		ieimpgraph weight2, title(Treatment effect on overall price)

		tab rep78, gen(n1_)
		drop n1_1

		regress price n1_*
		ieimpgraph n1_*


Fix another "==" -> "=" bashism.

Fix another "==" -> "=" bashism.

I notice it doesn't quite work on my Ubuntu system - if I "cd version"
and run "../redo", I get the following output:

   redo  all
   redo    vars
   redo      gitvars
   [: 24: %H: unexpected operator
   [: 24: %d: unexpected operator
   [: 24: %ci: unexpected operator

...and then a hang.

redo-ifchange gitvars.pre prodname

read PROD <prodname

# Fix each line from gitvars.pre where git may or may not have already
# substituted the variables.  If someone generated a tarball with 'git archive',
# then the data will have been substituted already.  If we're in a checkout of
# the git repo, then it won't, but we can just ask git to do the substitutions
# right now.
while read line; do
	# Lines *may* be of the form: $Format: ... $
	x=${line#\$Format:}  # remove prefix
	if [ "$x" != "$line" ]; then
		# git didn't substitute it
		x=${x%\$}  # remove trailing $
		if [ "$x" = "%d" ]; then
			tag=$(git describe --match="$PROD-*")
			x="(tag: $tag)"
		else
			x=$(git log -1 --pretty=format:"$x")
		fi
	fi
	echo "$x"
done <gitvars.pre

redo-ifchange gitvars.pre prodname

read PROD <prodname

# Fix each line from gitvars.pre where git may or may not have already
# substituted the variables.  If someone generated a tarball with 'git archive',
# then the data will have been substituted already.  If we're in a checkout of
# the git repo, then it won't, but we can just ask git to do the substitutions
# right now.
while read line; do
	# Lines *may* be of the form: $Format: ... $
	x=${line#\$Format:}  # remove prefix
	if [ "$x" != "$line" ]; then
		# git didn't substitute it
		x=${x%\$}  # remove trailing $
		if [ "$x" == "%d" ]; then
			tag=$(git describe --match="$PROD-*")
			x="(tag: $tag)"
		else
			x=$(git log -1 --pretty=format:"$x")
		fi
	fi
	echo "$x"
done <gitvars.pre


m1: include cnt module using new style

m1: include cnt module using new style

# -*-ruby-*-

{
  name: :m1,
  target: {family: 'Cyclone IV E', device: 'EP4CE22F17C6', eprom: 'EPCS64'},
  top: 'm1_de0nano',
  sim: 'm1_sim',
  pins: {
    sys_clk: {pad: 'R8', voltage: "3.3-V LVTTL",},
    # key: {pad: 'J15', voltage: "3.3-V LVTTL",},
    # rstn: {pad: 'E1', voltage: "3.3-V LVTTL",},
    leds: [
           {pad: 'A15', voltage: "3.3-V LVTTL", current: '4mA'},
           {pad: 'A13', voltage: "3.3-V LVTTL", current: '4mA'},
           {pad: 'B13', voltage: "3.3-V LVTTL", current: '4mA'},
           {pad: 'A11', voltage: "3.3-V LVTTL", current: '4mA'},
           {pad: 'D1', voltage: "3.3-V LVTTL", current: '4mA'},
           {pad: 'F3', voltage: "3.3-V LVTTL", current: '4mA'},
           {pad: 'B1', voltage: "3.3-V LVTTL", current: '4mA'},
           {pad: 'L3', voltage: "3.3-V LVTTL", current: '4mA'},
          ]
  },
  sdc: '../boards/de0-nano.sdc',
  files: ['*.v'],
  include: [:cnt],
}

# -*-ruby-*-

{
  name: :m1,
  target: {family: 'Cyclone IV E', device: 'EP4CE22F17C6', eprom: 'EPCS64'},
  top: 'm1_de0nano',
  sim: 'm1_sim',
  pins: {
    sys_clk: {pad: 'R8', voltage: "3.3-V LVTTL",},
    # key: {pad: 'J15', voltage: "3.3-V LVTTL",},
    # rstn: {pad: 'E1', voltage: "3.3-V LVTTL",},
    leds: [
           {pad: 'A15', voltage: "3.3-V LVTTL", current: '4mA'},
           {pad: 'A13', voltage: "3.3-V LVTTL", current: '4mA'},
           {pad: 'B13', voltage: "3.3-V LVTTL", current: '4mA'},
           {pad: 'A11', voltage: "3.3-V LVTTL", current: '4mA'},
           {pad: 'D1', voltage: "3.3-V LVTTL", current: '4mA'},
           {pad: 'F3', voltage: "3.3-V LVTTL", current: '4mA'},
           {pad: 'B1', voltage: "3.3-V LVTTL", current: '4mA'},
           {pad: 'L3', voltage: "3.3-V LVTTL", current: '4mA'},
          ]
  },
  sdc: '../boards/de0-nano.sdc',
  files: ['*.v', '../cnt/cnt.v'],
}