ieddtab - small typo in helpfile

ieddtab - small typo in helpfile

{smcl}
{* 09 Nov 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} [{help if}] [{help in}] [{help weight}],
	{cmdab:t:ime(}{it:varname}{cmd:)} {cmdab:treat:ment(}{it:varname}{cmd:)}
		{break}[
		{cmdab:covar:iates(}{it:varlist}{cmd:)} {cmdab:starl:evels(}{it:numlist}{cmd:)}
		{cmdab:stardrop}
		{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:nonumbers}
		{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:)}
	]

{pmore}Where {it:varlist} is a list of numeric continuous outcome variables (also called dependent variables or left hand side variables) to be used in the difference-in-difference regression(s) this command runs and presents the results from.{p_end}

{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:stardrop}}Suppresses all significance stars in all tables.{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}
{synopt :{cmdab:nonumbers}}Omit column numbers from table header in LaTeX 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. The levels specified in this option is ignored if {cmdab:stardrop} is used.{p_end}

{phang}{cmdab:stardrop}} suppresses all significance stars in all tables and remove the note on significance levels from the table note.{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} indicates 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}

{phang}{cmdab:nonumbers} ommits column numbers from table header in LaTeX output. Default is to display column numbers.{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}Nausheen Khan{break}Varnitha Kurli{break}Saori Iwamoto{break}Meyhar Mohammed{break}Michael Orevba{break}Matteo Ruzzante{break}Sakina Shibuya{break}Leonardo Viotti{break}

{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}
{* 09 Nov 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} [{help if}] [{help in}] [{help weight}],
	{cmdab:t:ime(}{it:varname}{cmd:)} {cmdab:treat:ment(}{it:varname}{cmd:)}
		{break}[
		{cmdab:covar:iates(}{it:varlist}{cmd:)} {cmdab:starl:evels(}{it:numlist}{cmd:)}
		{cmdab:stardrop}
		{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:nonumbers}
		{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:)}
	]

{pmore}Where {it:varlist} is a list of numeric continuous outcome variables (also called dependent variables or left hand side variables) to be used in the difference-in-difference regression(s) this command runs and presents the results from.{p_end}

{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:stardrop}}Suppresses all significance stars in all tables.{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}
{synopt :{cmdab:nonumbers}}Ommit column numbers from table header in LaTeX 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. The levels specified in this option is ignored if {cmdab:stardrop} is used.{p_end}

{phang}{cmdab:stardrop}} suppresses all significance stars in all tables and remove the note on significance levels from the table note.{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} indicates 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}

{phang}{cmdab:nonumbers} ommits column numbers from table header in LaTeX output. Default is to display column numbers.{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}Nausheen Khan{break}Varnitha Kurli{break}Saori Iwamoto{break}Meyhar Mohammed{break}Michael Orevba{break}Matteo Ruzzante{break}Sakina Shibuya{break}Leonardo Viotti{break}

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


add not explaining N

add not explaining N

cap program drop 	ieddtable
	program define	ieddtable

	syntax varlist, ///
					///
		t(varname numeric) tmt(varname numeric) 			///
		[ 													///
		COVARiates(varlist numeric)							///
		STARLevels(numlist descending min=3 max=3 >0 <1)	///
		STARSNOadd											///
		firstdiff											///
		rowlabtype(string) 									///
		rowlabtext(string)									///
		errortype(string)									///
		diformat(string)									///
		]

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

		Input handling

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

	*LABELS
	*Test and prepare the row lables and test how long the longest label is.
	prepRowLabels `varlist', rowlabtype("`rowlabtype'") rowlabtext("`rowlabtext'")
	local rowlabels "`r(rowlabels)'"
	local labmaxlen "`r(rowlabel_maxlen)'"

	*ERRORTYPES
	*If error type is used test that it is only one word and that word is an allowed error type
	if "`errortype'" != "" {
		local errortype = lower("`errortype'")
		if (`: word count `errortype'' != 1) | !inlist("`errortype'", "sd", "se", "errhide") {
			noi di as error "Value in option errortype(`errortype') can only one out of the following words; se, sd, errhide."
			error 198
		}
	}
	else {
		*No errortype specified use default which is standard errors
		local errortype "se"
	}

	*DEFAULT STAR LEVELS
	*Default star levels if option not used
	if "`starlevels'" == "" local starlevels ".1 .05 .01"

	** If the format option is specified, then test if there is a valid format specified
	if "`diformat'" != "" {

			** Creating a numeric mock variable that we attempt to apply the format
			*  to. This allows us to piggy back on Stata's internal testing to be
			*  sure that the format specified is at least one of the valid numeric
			*  formats in Stata
				tempvar  formattest
				gen 	`formattest' = 1
			cap	format  `formattest' `diformat'

			** Some error with the format
			if _rc == 120 {
				di as error "{phang}The format specified in diformat(`diformat') is not a valid Stata format. See {help format} for a list of valid Stata formats. This command only accept the f, fc, g, gc and e format.{p_end}"
				error 120
			}
			else if _rc != 0 {
				di as error "{phang}Something unexpected happened related to the option diformat(`diformat'). Make sure that the format you specified is a valid format. See {help format} for a list of valid Stata formats. If this problem remains, please report this error at https://github.com/worldbank/ietoolkit.{p_end}"
				error _rc
			}

			** Format is a valid format, but is it one we allow
			else {

				local fomrmatAllowed 0
				local charLast  = substr("`diformat'", -1,.)
				local char2Last = substr("`diformat'", -2,.)

				if  "`charLast'" == "f" | "`charLast'" == "e" {
					local fomrmatAllowed 1
				}
				else if "`charLast'" == "g" {
					if "`char2Last'" == "tg" {
						*format tg not allowed. all other valid formats ending on g are allowed
						local fomrmatAllowed 0
					}
					else {

						*Formats that end in g that is not tg can only be g which is allowed.
						local fomrmatAllowed 1
					}
				}
				else if  "`charLast'" == "c" {
					if "`char2Last'" != "gc" & "`char2Last'" != "fc" {
						*format ends on c but is neither fc nor gc
						local fomrmatAllowed 0
					}
					else {

						*Formats that end in c that are either fc or gc are allowed.
						local fomrmatAllowed 1
					}
				}
				else {
					*format is neither f, fc, g, gc nor e
					local fomrmatAllowed 0
				}
				if `fomrmatAllowed' == 0 {
					di as error "{phang}The format specified in diformat(`diformat') is not allowed. Only format f, fc, g, gc and e are allowed. See {help format} for details on Stata formats.{p_end}"
					error 120
				}
			}
		}
		else {
			*Default value if fomramt not specified
			local diformat = "%9.2f"
		}

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

		Initiate the result matrix

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

	*Creates the template for the result matrix in a subfunction
	templateResultMatrix
	mat startRow = r(startRow)
	local colnames = "`r(colnames)'"

	*Remove this when ready for production
	//noi di "Start row to see headers, remove for production"
	//matlist startRow // See the default row with its column names

	*Initiate the result matrix with a place holder row that will not be used for anything. Matrices cannot be initiated empty
	mat ddtab_resultMap = startRow
	mat rownames ddtab_resultMap = placeholder

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

		Loop over all variables and prepare the data

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

	foreach var of local varlist {

		//noi di "Variable `var'"

		*Each variable is a row in the result matrix
		mat `var' = startRow
		mat rownames `var' = `var'
		mat colnames `var' = `colnames'

		*Local that keeps track of which column to fill
		local colindex 0

		tempvar regsample

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

			Calculating 2nd difference and restict the sample
			for this output var

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

		*Run the regression to get the double difference
		qui reg `var' `tmt'#`t' `covariates'
		mat resTable = r(table)

		//noi di "Rest table 2nd diff: reg `var' `tmt'#`t' `covariates'"
		//matlist resTable

		**This is why this is done first. All other calculations
		* for this outcome var should be restricted to this sample.
		gen `regsample' = e(sample)
		local N `e(N)'

		**Test that the dummy vars creates for valid groups for each
		* combination of time and treat in the sample used for this outcome var
		testDDdums `t' `tmt' `regsample' `var'  //comment in when this is made into a command

		*Get the second differnce
		local ++colindex
		mat `var'[1,`colindex'] =  el(resTable,1,4)

		*Get the standard error of second difference
		local ++colindex
		convertErrs el(resTable,2,4) `N' "`errortype'"
		mat `var'[1,`colindex'] =  `r(converted_error)'

		*Get the number of stars using sub-command countStars
		local ++colindex
		local pvalue = el(resTable,4,4)
		countStars `pvalue' `starlevels'
		mat `var'[1,`colindex'] = `r(stars)'

		*Get the N of second difference regression
		local ++colindex
		mat `var'[1,`colindex'] = `N'

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

			Calculating 1st differences

		*************/
		forvalues tmt01 = 0/1 {

			*Regress time against the outcome var one tmt group at the time
			qui reg `var' `t' `covariates' if `tmt' == `tmt01' & `regsample' == 1
			mat resTable = r(table)

			//noi di "Rest table 1st diff: reg `var' `t' `covariates' if `tmt' == `tmt01' & `regsample' == 1"
			//matlist resTable

			//Get the 1st diff
			local ++colindex
			mat `var'[1,`colindex'] =  el(resTable,1,1)

			*Get the standard error of 1st diff
			local ++colindex
			convertErrs el(resTable,2,1) `e(N)' "`errortype'"
			mat `var'[1,`colindex'] =  `r(converted_error)'

			*Get the number of stars using sub-command countStars
			local ++colindex
			local pvalue = el(resTable,4,4)
			countStars `pvalue' `starlevels'
			mat `var'[1,`colindex'] = `r(stars)'

			*Get the N of first difference regression
			local ++colindex
			mat `var'[1,`colindex'] =  `e(N)'

		}

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

			Calculating standard means for all groups

		*************/
		forvalues tmt01 = 0/1 {
			forvalues t01 = 0/1 {

				*Summary stats on this group
				qui mean `var' if `tmt' == `t01' & `t' == `tmt01' & `regsample' == 1

				mat resTable = r(table)

				//Get the mean
				local ++colindex
				mat `var'[1,`colindex'] =  el(resTable,1,1)

				*Get the standard error of the mean
				local ++colindex
				convertErrs el(resTable,2,1)  `e(N)' "`errortype'"
				mat `var'[1,`colindex'] =  `r(converted_error)'

				*Get the N of the ordinary means regressions
				local ++colindex
				mat `var'[1,`colindex'] =  `e(N)'
			}
		}

		*Append this row to the result table
		mat 	ddtab_resultMap = (ddtab_resultMap \ `var')

	}

	*Remove placeholder row
	matrix ddtab_resultMap = ddtab_resultMap[2..., 1...]

	*Show the final matrix will all data needed to start building the output
	//noi di "Matlist with results"
	//matlist ddtab_resultMap

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

		Output table in result window

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

	outputwindow `varlist' , ddtab_resultMap(ddtab_resultMap) labmaxlen(`labmaxlen') rwlbls(`rowlabels') ///
		starlevels("`starlevels'") covariates(`covariates') `errortype' diformat(`diformat')

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

		Output table in LaTeX

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

	if "`savetex'" != "" {

		//outputtex `varlist' , ddtab_resultMap(ddtab_resultMap) savetex(`savetex')

	}

end

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

	Write sub-commands for input handling

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

**Program to prepare row labels for each outcome var, using variable name,
* variable label or manually entered labels depedning on user input. Variable
* names are used if no input.
cap program drop 	prepRowLabels
	program define	prepRowLabels, rclass

	syntax varlist, [rowlabtype(string) rowlabtext(string)]

	*First test input
	if "`rowlabtype'" == "varlab" | "`rowlabtype'" == "" | "`rowlabtype'" == "varname" {
		//All is good do nothing
	}
	else {
		noi display as error "{phang}Row label type [`rowlabtype'] is not a valid row label type. Enter either {it:varlab} or {it:varname} (the default if not specified is {it:varname}). See option {help ieddtable:rowlabtype} for details."
		error 198
	}

	/*************
		Parse through the manually entered labels
	*************/

	*Create a local with the rowlabel input to be tokenized
	local row_labels_to_tokenize `rowlabtext'

	while "`row_labels_to_tokenize'" != "" {

		*Parsing name and label pair
		gettoken nameAndLabel row_labels_to_tokenize : row_labels_to_tokenize, parse("@@")

		*Splitting name and label
		gettoken name label : nameAndLabel

		/*
			We store two locals, one with varnames and one with label. They are
			stored in the same order, so if we find varname we know we will find
			the corresponding label in the same order in the other local.
		*/

		*** Tests

		*Checking that the variables used in rowlabels() are included in the table
		local name_correct : list name in varlist
		if `name_correct' == 0 {
			noi display as error "{phang}Variable [`name'] listed in rowlabtext(`rowlabtext') is not found among the outcome variables."
			error 111
		}

		*Testing that no label is missing
		if "`label'" == "" {
			noi display as error "{phang}For variable [`name'] listed in rowlabtext(`rowlabels') you have not specified any label. Labels are requried for all variables listed in rowlabels(). Variables omitted from rowlabtext() will be assigned labels according to the rule in rowlabtype(). See also option {help ieddtable:rowlabtext}"
			error 198
		}

		*Storing the name in local to be used to get index of corresponding label in the second local
		local rowLabelNames `"`rowLabelNames' "`name'" "'

		*Removing leading or trailing spaces and store label with the same index as in the name local above
		local label = trim("`label'")
		local rowLabelLabels `"`rowLabelLabels' "`label'" "'

		*Parse char is not removed by gettoken, so remove it and start over
		local row_labels_to_tokenize = subinstr("`row_labels_to_tokenize'" ,"@@","",1)
	}

	**Set up locals to be returned. One with row labels without varname but in
	* final order, and one local with length of longest label
	local preppedRowLabels
	local maxLen 0

	*Loop over all varaibles and prepare the labels
	foreach var of local varlist {

		**Get the index of this variable in manually entered labels. Index is
		* zero if no manually entered label for this variable
		local rowLabPos : list posof "`var'" in rowLabelNames

		if `rowLabPos' == 0 {

			*No label was manually entered for this variable, use the other rules
			if "`rowlabtype'" == "varlab" {
				local this_label : variable label `var'		//Use variable label
			}
			else {

				local this_label `var'						//Default, use varname

			}
		}
		else {
			*Getting the manually defined label corresponding to this variable
			local this_label : word `rowLabPos' of `rowLabelLabels'
		}

		*Update the two locals that will be returned
		local preppedRowLabels "`preppedRowLabels' @@`this_label'"	//Prepare the final list
		local maxLen = max(strlen("`this_label'"),`maxLen')	//Store the length on the longest label, used on some outputs
	}

	*Return the locals
	return local rowlabels `preppedRowLabels'
	return local rowlabel_maxlen `maxLen'

end

** Program that test the t and tmt variables are valid dummies
*  for a Diff-in-Diff. I.e. they are both dummies and there are
*  at least 2 observations in each combination (0,0), (1,0),
*  (0,1) and (1,1)
cap program drop 	testDDdums
	program define	testDDdums

		args time treat samplevar outputvar

		*Test taht the dummies are dummies
		foreach dummy in `time' `treat' {

			cap assert inlist(`dummy',1,0) | missing(`dummy') | `samplevar' == 0
			if _rc {
				noi di as error "{phang}In the difference in differnce regression for outputvar [`outputvar'], the dummy [`dummy'] is not a real dummy as it has values differnt from 1 and 0. See tab below. The tab is restricted to the observations that are not excluded due to missing values etc. in the difference in differnce regression.{p_end}""
				noi tab `dummy' if `samplevar' == 1, missing
				error 480
			}
		}

		**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.

		*Test that there is some observations in each group
		forvalues tmt01 = 0/1 {
			forvalues t01 = 0/1 {

				*Summary stats on this group
				qui count if `treat' == `t01' & `time' == `tmt01' & `samplevar' == 1

				//There got to be more than 1 observation in each group for the regression to make sense
				if `r(N)' < 2 {
					noi di as error "{phang}In the difference in differnce regression for outputvar [`outputvar'] there were not enough observations in each combination of treatment [`treat'] and time [`time']. The tab below is restricted to the observations that are not excluded due to missing values etc. in the difference in differnce regression.{p_end}""
					noi tab `treat' `time' if `samplevar' == 1, missing
					error 480

				}
			}
		}

	end

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

	Write sub-commands for stats

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

*Sets up template for the result matrix
cap program drop 	templateResultMatrix
	program define	templateResultMatrix, rclass

	*Set the names of the different columns in the result Matrix
	local 2ndDiff_cols 			2D 2D_err 2D_stars 2D_N

	local 1stDiff_C_cols		1DC 1DC_err 1DC_stars 1DC_N
	local 1stDiff_T_cols		1DT 1DT_err 1DT_stars 1DT_N

	local basicMean_C0_cols		C0_mean C0_err C0_N
	local basicMean_T0_cols		T0_mean T0_err T0_N
	local basicMean_C1_cols		C1_mean C1_err C1_N
	local basicMean_T1_cols		T1_mean T1_err T1_N

	local colnames `2ndDiff_cols' `1stDiff_C_cols' `1stDiff_T_cols' `basicMean_C0_cols' `basicMean_T0_cols' `basicMean_C1_cols' `basicMean_T0_cols'

	*Define default row here. The results for each var will be one row that starts with all missing vlaues
	mat startRow = (.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.)
	mat colnames startRow = `colnames'

	return matrix startRow startRow
	return local colnames `colnames'

end

*Take the significance levels and count number of starts
cap program drop 	countStars
	program define	countStars, rclass

	args pvalue star1 star2 star3

	local stars 0
	foreach star_p_level in `star1' `star2' `star3' {

		if `pvalue' < `star_p_level' local ++stars
	}

	return local stars `stars'

end

**Convert the errors to the display stats picked
* by the user. Standard errors is the default.
cap program drop 	convertErrs
	program define	convertErrs, rclass

	args se_err N errortype

	*Test if custom star levels are used
	if "`errortype'" == "sd" {
		local err = `se_err' * sqrt(`N')
	}
	else {
		//For se keep se, for errhide keep se as matrix must have some value even if it will not be used
		local err = `se_err'
	}

	return local converted_error `err'

end

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

	Write sub-commands for outputs

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

	/******
	The result matrix can be passed into subcommands that output in either Excel, LaTeX or in the main window.

	The name of the result matrix is ddtab_resultMap. It can be refernced like this ddtab_resultMap[row, col] where
	row is the variable order where 1 is the first varaible in the varlist and col is the name of the stat.

	You always must make it first in to a 1x1 matrix, and then make that a local.

	*/

	*The results can be accessed like this, which makes the sub-commands less sensitive to changing column order in the section above.
	//mat A = ddtab_resultMap[3, "C0_Mean"] // returns a 1x1 matrix with the baseline mean for the countrol grop for the thrid outcome var
	//local a = el(A,1,1)				// returns the value

	//matlist A
	//di `a'

	/*
		Column name dictionary
			Differences:
			- 2D : Second differnce coefficient (t*tmt == 1)
			- 1DC : First  differnce coefficient control (t == 0)
			- 1DT : First  differnce coefficient treatment (tmt == 0)

			for each coefficent these stats are also provided:
				- _err : Second differnce errors (type of errors is set in command errortype)
				- _stars :  Second Differene - The number of significance stars (sig level set in command)
				- _N : Second Difference - Number of observtions in the regression

			Group means:
			- C0 - Control time 0
			- T0 - Treatment time 0
			- C1 - Control time 1
			- T1 - Treatment time 1

			for each group these stats are also provided:
				- _mean : the mean of the group
				- _err : the error in the mean (type of errors is set in command errortype)
				- _N : number of observations in baseline means

	*/

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

		Output table in result window

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

	cap program drop 	outputwindow
		program define	outputwindow

		syntax varlist , ddtab_resultMap(name) labmaxlen(numlist) rwlbls(string) starlevels(string) diformat(string) [covariates(string) errhide sd se]

		*Prepare lables for the erorrs to be displayed (in case any)
		if "`sd'" != "" local errlabel "SD"
		if "`se'" != "" local errlabel "SE"

		*Count numbers of variables to loop over
		local numVars = `:word count `varlist''

		*List of variabls to display and loop over when formatting
		local statlist 2D 1DT 1DC C0_mean T0_mean 2D_err 1DT_err 1DC_err C0_err T0_err 2D_N 1DT_N 1DC_N C0_N T0_N

		*************************
		* Table width for label column

		local first_hhline = 2 + `labmaxlen'
		local first_col = 4 + `labmaxlen'

		*************************
		* Table width for basline columns

		local bsln_space = 2
		local bsln_stat_left = `bsln_space' + 1
		local bsln_width = ((`bsln_space' * 2) + 8)

		*************************
		* Table width for first difference column

		local diff_space = 3
		local diff_stat_left = `diff_space' + 1
		local diff_width = ((`diff_space' * 2) + 10)

		*************************
		* Table width control column

		local ctrl_hline = `bsln_width' + 1 + `diff_width'
		local ctrl_space = (`ctrl_hline' - 7) / 2

		*************************
		* Table width treatment column

		local tmt_hline = `bsln_width' + 1 + `diff_width'
		local tmt_space = (`tmt_hline' - 9) / 2

		*************************
		* Table width diff diff column

		local didi_stat_left = 4
		local diffdiff_width  = 17

		*************************
		* Calculate stats column indexes

		local bsln_c_col	= `first_col'  + `bsln_width' + 1
		local diff_c_col	= `bsln_c_col' + `diff_width' + 1
		local bsln_t_col	= `diff_c_col' + `bsln_width' + 1
		local diff_t_col	= `bsln_t_col' + `diff_width' + 1
		local didi_col		= `diff_t_col' + `diffdiff_width' + 1

		*************************
		* Start writing table

		*Three title rows
		noi di as text "{c TLC}{hline `first_hhline'}{c TT}{hline `ctrl_hline'}{c TT}{hline `tmt_hline'}{c TT}{hline 17}{c TRC}"
		noi di as text "{c |}{col `first_col'}{c |}{dup `ctrl_space': }Control{dup `ctrl_space': }{c |}{dup `tmt_space': }Treatment{dup `tmt_space': }{c |}  Difference-in  {c |}"
		noi di as text "{c |}{col `first_col'}{c |}{dup `bsln_space': }Baseline{dup `bsln_space': }{c |}{dup `diff_space': }Difference{dup `diff_space': }{c |}{dup `bsln_space': }Baseline{dup `bsln_space': }{c |}{dup `diff_space': }Difference{dup `diff_space': }{c |}   -difference   {c |}"

		*Stats titels, show the stats displayed for each column in the order they are displayed
		noi di as text "{c |}{col `first_col'}{c |}{dup `bsln_stat_left': } Mean{col `bsln_c_col'}{c |}{dup `diff_stat_left': } Coef{col `diff_c_col'}{c |}{dup `bsln_stat_left': } Mean{col `bsln_t_col'}{c |}{dup `diff_stat_left': } Coef{col `diff_t_col'}{c |}{dup `didi_stat_left': } Coef{col `didi_col'}{c |}"
		if "`errhide'" == "" {
			noi di as text "{c |}{col `first_col'}{c |}{dup `bsln_stat_left': }(`errlabel'){col `bsln_c_col'}{c |}{dup `diff_stat_left': }(`errlabel'){col `diff_c_col'}{c |}{dup `bsln_stat_left': }(`errlabel'){col `bsln_t_col'}{c |}{dup `diff_stat_left': }(`errlabel'){col `diff_t_col'}{c |}{dup `didi_stat_left': }(`errlabel'){col `didi_col'}{c |}"
		}
		noi di as text "{c |}{col 3}Variable{col `first_col'}{c |}{dup `bsln_stat_left': } N{col `bsln_c_col'}{c |}{dup `diff_stat_left': } N{col `diff_c_col'}{c |}{dup `bsln_stat_left': } N{col `bsln_t_col'}{c |}{dup `diff_stat_left': } N{col `diff_t_col'}{c |}{dup `didi_stat_left': } N{col `didi_col'}{c |}"

		*Bottom row to table header
		noi di as text "{c LT}{hline `first_hhline'}{c +}{hline `bsln_width'}{c +}{hline `diff_width'}{c +}{hline `bsln_width'}{c +}{hline `diff_width'}{c +}{hline 17}{c RT}"

		*Loop over each variable and prepare the row
		forvalues row = 1/`numVars' {

			*Get lables from the list of lables previosly prepared
			local rwlbls = trim(subinstr("`rwlbls'", "@@","", 1))
			gettoken label rwlbls : rwlbls, parse("@@")

			*Loop over all the stats for this variable
			foreach stat of local statlist {

				**Run sub command that gets value from matrix and prepares it
				* in the format suitable for the result window table (and adding
				* stars if applicable)
				windowdiformat , statname("`stat'") row(`row') ddtab_resultMap(ddtab_resultMap) diformat("`diformat'") bslnw(`bsln_width') diffw(`diff_width') ddw(`diffdiff_width')

				*The main stat
				local `stat' `r(disp_stata)'

				*The number of spaces before the stat in the colum
				local `stat'_space = `r(disp_pre_space)'
			}

			*Disaplay each variable row at the same time
			noi di as text "{c |} `label'{col `first_col'}{c |}{dup `C0_mean_space': }`C0_mean'{dup `1DC_space': }`1DC'{dup `T0_mean_space': }`T0_mean'{dup `1DT_space': }`1DT'{dup `2D_space': }`2D'"

			*Unless error type is errhide, show the errors on a seperate row
			if "`errhide'" == "" {
				noi di as text "{c |}{col `first_col'}{c |}{dup `C0_err_space': }`C0_err'{dup `1DC_err_space': }`1DC_err'{dup `T0_err_space': }`T0_err'{dup `1DT_err_space': }`1DT_err'{dup `2D_err_space': }`2D_err'"
			}

			*The number of observations are shown on a separate row
			noi di as text "{c |}{col `first_col'}{c |}{dup `C0_N_space': }`C0_N'{dup `1DC_N_space': }`1DC_N'{dup `T0_N_space': }`T0_N'{dup `1DT_N_space': }`1DT_N'{dup `2D_N_space': }`2D_N'"

		}

		*Add bottom notes to the table
		noi di as text "{c BLC}{hline `first_hhline'}{c BT}{hline `bsln_width'}{c BT}{hline `diff_width'}{c BT}{hline `bsln_width'}{c BT}{hline `diff_width'}{c BT}{hline 17}{c BRC}"

		*************************
		* Write notes below the table

		noi di as text "  The baseline means only includes observations not omitted in the 1st and 2nd differences."

		*Show stars levels
		local star1_value : word 1 of `starlevels'
		local star2_value : word 2 of `starlevels'
		local star3_value : word 3 of `starlevels'
		noi di as text "  ***, **, and * indicate significance at the `star3_value', `star2_value', and `star1_value' percent critical level. "

		*List covariates used
		if ("`covariates'" != "") {
			noi di as text "  The following variable(s) was included as covariates [`covariates']"
		}

	end

cap program drop 	windowdiformat
	program define	windowdiformat, rclass

	syntax , statname(string) row(numlist) ddtab_resultMap(name) diformat(string)  bslnw(numlist) diffw(numlist) ddw(numlist)

		local numSpace 0

		mat temp = ddtab_resultMap[`row', "`statname'"]
		local `statname' = el(temp,1,1)

		if substr("`statname'", -2,.) == "_N" {
			local `statname'	: display %9.0f ``statname''
		}
		else {
			local `statname' 	: display `diformat' ``statname''
		}

		*Trime spaces on left from left.
		local `statname' = ltrim("``statname''")

		*For coefficients, add stars if applicable
		if inlist("`statname'", "2D", "1DT", "1DC") {

			mat starNumMat = ddtab_resultMap[`row', "`statname'_stars"]
			local starNum = el(starNumMat,1,1)

			if `starNum' == 0 local `statname' "``statname''    "
			if `starNum' == 1 local `statname' "``statname''*   "
			if `starNum' == 2 local `statname' "``statname''**  "
			if `starNum' == 3 local `statname' "``statname''*** "
		}

		*Add brackets to errors
		if inlist("`statname'", "2D_err", "1DT_err", "1DC_err", "C0_err", "T0_err") {
			local `statname' "(``statname'')"
		}

		*Get the lengt of the characters to display
		local len = strlen("``statname''")

		*Which column for this stat
		local colName = substr("`statname'", 1, 2)

		*Get corresponding width for that col
		if "`colName'" == "C0" local colw = `bslnw'
		if "`colName'" == "T0" local colw = `bslnw'
		if "`colName'" == "1D" local colw = `diffw'
		if "`colName'" == "2D" local colw = `ddw'

		* Calculate the number of spaces needed bofore
		* the value and add spaces after it
		if inlist("`statname'", "C0_mean", "T0_mean", "C0_N", "T0_N") {
			*Baseline mean values
			return local disp_stata "``statname''  {c |}"
			local numSpace = `colw' - `len' - 2
		}
		else if inlist("`statname'", "C0_err", "T0_err") {
			*Baseline mean values errors
			return local disp_stata "``statname'' {c |}"
			local numSpace = `colw' - `len' - 1
		}
		else if inlist("`statname'", "1DT", "1DC", "2D") {
			*First difference coefficent
			return local disp_stata "``statname''{c |}"
			local numSpace = `colw' - `len'
		}
		else if inlist("`statname'", "1DT_N", "1DC_N", "2D_N") {
			*First difference coefficent
			return local disp_stata "``statname''    {c |}"
			local numSpace = `colw' - `len' - 4
		}
		else if inlist("`statname'", "1DT_err", "1DC_err", "2D_err")  {
			*First difference coefficient error
			return local disp_stata "``statname''   {c |}"
			local numSpace = `colw' - `len' - 3
		}

		**If numbers are so big that numSapce is negative, set it to 0 as
		* numSpace cannot be negative. Table will show incorrectly but
		* will display.
		if `numSpace' < 0 local numSpace 0

		return local disp_pre_space = `numSpace'
		return local disp_len = `len'

	end

cap program drop 	ieddtable
	program define	ieddtable

	syntax varlist, ///
					///
		t(varname numeric) tmt(varname numeric) 			///
		[ 													///
		COVARiates(varlist numeric)							///
		STARLevels(numlist descending min=3 max=3 >0 <1)	///
		STARSNOadd											///
		firstdiff											///
		rowlabtype(string) 									///
		rowlabtext(string)									///
		errortype(string)									///
		diformat(string)									///
		]

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

		Input handling

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

	*LABELS
	*Test and prepare the row lables and test how long the longest label is.
	prepRowLabels `varlist', rowlabtype("`rowlabtype'") rowlabtext("`rowlabtext'")
	local rowlabels "`r(rowlabels)'"
	local labmaxlen "`r(rowlabel_maxlen)'"

	*ERRORTYPES
	*If error type is used test that it is only one word and that word is an allowed error type
	if "`errortype'" != "" {
		local errortype = lower("`errortype'")
		if (`: word count `errortype'' != 1) | !inlist("`errortype'", "sd", "se", "errhide") {
			noi di as error "Value in option errortype(`errortype') can only one out of the following words; se, sd, errhide."
			error 198
		}
	}
	else {
		*No errortype specified use default which is standard errors
		local errortype "se"
	}

	*DEFAULT STAR LEVELS
	*Default star levels if option not used
	if "`starlevels'" == "" local starlevels ".1 .05 .01"

	** If the format option is specified, then test if there is a valid format specified
	if "`diformat'" != "" {

			** Creating a numeric mock variable that we attempt to apply the format
			*  to. This allows us to piggy back on Stata's internal testing to be
			*  sure that the format specified is at least one of the valid numeric
			*  formats in Stata
				tempvar  formattest
				gen 	`formattest' = 1
			cap	format  `formattest' `diformat'

			** Some error with the format
			if _rc == 120 {
				di as error "{phang}The format specified in diformat(`diformat') is not a valid Stata format. See {help format} for a list of valid Stata formats. This command only accept the f, fc, g, gc and e format.{p_end}"
				error 120
			}
			else if _rc != 0 {
				di as error "{phang}Something unexpected happened related to the option diformat(`diformat'). Make sure that the format you specified is a valid format. See {help format} for a list of valid Stata formats. If this problem remains, please report this error at https://github.com/worldbank/ietoolkit.{p_end}"
				error _rc
			}

			** Format is a valid format, but is it one we allow
			else {

				local fomrmatAllowed 0
				local charLast  = substr("`diformat'", -1,.)
				local char2Last = substr("`diformat'", -2,.)

				if  "`charLast'" == "f" | "`charLast'" == "e" {
					local fomrmatAllowed 1
				}
				else if "`charLast'" == "g" {
					if "`char2Last'" == "tg" {
						*format tg not allowed. all other valid formats ending on g are allowed
						local fomrmatAllowed 0
					}
					else {

						*Formats that end in g that is not tg can only be g which is allowed.
						local fomrmatAllowed 1
					}
				}
				else if  "`charLast'" == "c" {
					if "`char2Last'" != "gc" & "`char2Last'" != "fc" {
						*format ends on c but is neither fc nor gc
						local fomrmatAllowed 0
					}
					else {

						*Formats that end in c that are either fc or gc are allowed.
						local fomrmatAllowed 1
					}
				}
				else {
					*format is neither f, fc, g, gc nor e
					local fomrmatAllowed 0
				}
				if `fomrmatAllowed' == 0 {
					di as error "{phang}The format specified in diformat(`diformat') is not allowed. Only format f, fc, g, gc and e are allowed. See {help format} for details on Stata formats.{p_end}"
					error 120
				}
			}
		}
		else {
			*Default value if fomramt not specified
			local diformat = "%9.2f"
		}

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

		Initiate the result matrix

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

	*Creates the template for the result matrix in a subfunction
	templateResultMatrix
	mat startRow = r(startRow)
	local colnames = "`r(colnames)'"

	*Remove this when ready for production
	//noi di "Start row to see headers, remove for production"
	//matlist startRow // See the default row with its column names

	*Initiate the result matrix with a place holder row that will not be used for anything. Matrices cannot be initiated empty
	mat ddtab_resultMap = startRow
	mat rownames ddtab_resultMap = placeholder

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

		Loop over all variables and prepare the data

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

	foreach var of local varlist {

		//noi di "Variable `var'"

		*Each variable is a row in the result matrix
		mat `var' = startRow
		mat rownames `var' = `var'
		mat colnames `var' = `colnames'

		*Local that keeps track of which column to fill
		local colindex 0

		tempvar regsample

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

			Calculating 2nd difference and restict the sample
			for this output var

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

		*Run the regression to get the double difference
		qui reg `var' `tmt'#`t' `covariates'
		mat resTable = r(table)

		//noi di "Rest table 2nd diff: reg `var' `tmt'#`t' `covariates'"
		//matlist resTable

		**This is why this is done first. All other calculations
		* for this outcome var should be restricted to this sample.
		gen `regsample' = e(sample)
		local N `e(N)'

		**Test that the dummy vars creates for valid groups for each
		* combination of time and treat in the sample used for this outcome var
		testDDdums `t' `tmt' `regsample' `var'  //comment in when this is made into a command

		*Get the second differnce
		local ++colindex
		mat `var'[1,`colindex'] =  el(resTable,1,4)

		*Get the standard error of second difference
		local ++colindex
		convertErrs el(resTable,2,4) `N' "`errortype'"
		mat `var'[1,`colindex'] =  `r(converted_error)'

		*Get the number of stars using sub-command countStars
		local ++colindex
		local pvalue = el(resTable,4,4)
		countStars `pvalue' `starlevels'
		mat `var'[1,`colindex'] = `r(stars)'

		*Get the N of second difference regression
		local ++colindex
		mat `var'[1,`colindex'] = `N'

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

			Calculating 1st differences

		*************/
		forvalues tmt01 = 0/1 {

			*Regress time against the outcome var one tmt group at the time
			qui reg `var' `t' `covariates' if `tmt' == `tmt01' & `regsample' == 1
			mat resTable = r(table)

			//noi di "Rest table 1st diff: reg `var' `t' `covariates' if `tmt' == `tmt01' & `regsample' == 1"
			//matlist resTable

			//Get the 1st diff
			local ++colindex
			mat `var'[1,`colindex'] =  el(resTable,1,1)

			*Get the standard error of 1st diff
			local ++colindex
			convertErrs el(resTable,2,1) `e(N)' "`errortype'"
			mat `var'[1,`colindex'] =  `r(converted_error)'

			*Get the number of stars using sub-command countStars
			local ++colindex
			local pvalue = el(resTable,4,4)
			countStars `pvalue' `starlevels'
			mat `var'[1,`colindex'] = `r(stars)'

			*Get the N of first difference regression
			local ++colindex
			mat `var'[1,`colindex'] =  `e(N)'

		}

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

			Calculating standard means for all groups

		*************/
		forvalues tmt01 = 0/1 {
			forvalues t01 = 0/1 {

				*Summary stats on this group
				qui mean `var' if `tmt' == `t01' & `t' == `tmt01' & `regsample' == 1

				mat resTable = r(table)

				//Get the mean
				local ++colindex
				mat `var'[1,`colindex'] =  el(resTable,1,1)

				*Get the standard error of the mean
				local ++colindex
				convertErrs el(resTable,2,1)  `e(N)' "`errortype'"
				mat `var'[1,`colindex'] =  `r(converted_error)'

				*Get the N of the ordinary means regressions
				local ++colindex
				mat `var'[1,`colindex'] =  `e(N)'
			}
		}

		*Append this row to the result table
		mat 	ddtab_resultMap = (ddtab_resultMap \ `var')

	}

	*Remove placeholder row
	matrix ddtab_resultMap = ddtab_resultMap[2..., 1...]

	*Show the final matrix will all data needed to start building the output
	//noi di "Matlist with results"
	//matlist ddtab_resultMap

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

		Output table in result window

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

	outputwindow `varlist' , ddtab_resultMap(ddtab_resultMap) labmaxlen(`labmaxlen') rwlbls(`rowlabels') ///
		starlevels("`starlevels'") covariates(`covariates') `errortype' diformat(`diformat')

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

		Output table in LaTeX

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

	if "`savetex'" != "" {

		//outputtex `varlist' , ddtab_resultMap(ddtab_resultMap) savetex(`savetex')

	}

end

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

	Write sub-commands for input handling

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

**Program to prepare row labels for each outcome var, using variable name,
* variable label or manually entered labels depedning on user input. Variable
* names are used if no input.
cap program drop 	prepRowLabels
	program define	prepRowLabels, rclass

	syntax varlist, [rowlabtype(string) rowlabtext(string)]

	*First test input
	if "`rowlabtype'" == "varlab" | "`rowlabtype'" == "" | "`rowlabtype'" == "varname" {
		//All is good do nothing
	}
	else {
		noi display as error "{phang}Row label type [`rowlabtype'] is not a valid row label type. Enter either {it:varlab} or {it:varname} (the default if not specified is {it:varname}). See option {help ieddtable:rowlabtype} for details."
		error 198
	}

	/*************
		Parse through the manually entered labels
	*************/

	*Create a local with the rowlabel input to be tokenized
	local row_labels_to_tokenize `rowlabtext'

	while "`row_labels_to_tokenize'" != "" {

		*Parsing name and label pair
		gettoken nameAndLabel row_labels_to_tokenize : row_labels_to_tokenize, parse("@@")

		*Splitting name and label
		gettoken name label : nameAndLabel

		/*
			We store two locals, one with varnames and one with label. They are
			stored in the same order, so if we find varname we know we will find
			the corresponding label in the same order in the other local.
		*/

		*** Tests

		*Checking that the variables used in rowlabels() are included in the table
		local name_correct : list name in varlist
		if `name_correct' == 0 {
			noi display as error "{phang}Variable [`name'] listed in rowlabtext(`rowlabtext') is not found among the outcome variables."
			error 111
		}

		*Testing that no label is missing
		if "`label'" == "" {
			noi display as error "{phang}For variable [`name'] listed in rowlabtext(`rowlabels') you have not specified any label. Labels are requried for all variables listed in rowlabels(). Variables omitted from rowlabtext() will be assigned labels according to the rule in rowlabtype(). See also option {help ieddtable:rowlabtext}"
			error 198
		}

		*Storing the name in local to be used to get index of corresponding label in the second local
		local rowLabelNames `"`rowLabelNames' "`name'" "'

		*Removing leading or trailing spaces and store label with the same index as in the name local above
		local label = trim("`label'")
		local rowLabelLabels `"`rowLabelLabels' "`label'" "'

		*Parse char is not removed by gettoken, so remove it and start over
		local row_labels_to_tokenize = subinstr("`row_labels_to_tokenize'" ,"@@","",1)
	}

	**Set up locals to be returned. One with row labels without varname but in
	* final order, and one local with length of longest label
	local preppedRowLabels
	local maxLen 0

	*Loop over all varaibles and prepare the labels
	foreach var of local varlist {

		**Get the index of this variable in manually entered labels. Index is
		* zero if no manually entered label for this variable
		local rowLabPos : list posof "`var'" in rowLabelNames

		if `rowLabPos' == 0 {

			*No label was manually entered for this variable, use the other rules
			if "`rowlabtype'" == "varlab" {
				local this_label : variable label `var'		//Use variable label
			}
			else {

				local this_label `var'						//Default, use varname

			}
		}
		else {
			*Getting the manually defined label corresponding to this variable
			local this_label : word `rowLabPos' of `rowLabelLabels'
		}

		*Update the two locals that will be returned
		local preppedRowLabels "`preppedRowLabels' @@`this_label'"	//Prepare the final list
		local maxLen = max(strlen("`this_label'"),`maxLen')	//Store the length on the longest label, used on some outputs
	}

	*Return the locals
	return local rowlabels `preppedRowLabels'
	return local rowlabel_maxlen `maxLen'

end

** Program that test the t and tmt variables are valid dummies
*  for a Diff-in-Diff. I.e. they are both dummies and there are
*  at least 2 observations in each combination (0,0), (1,0),
*  (0,1) and (1,1)
cap program drop 	testDDdums
	program define	testDDdums

		args time treat samplevar outputvar

		*Test taht the dummies are dummies
		foreach dummy in `time' `treat' {

			cap assert inlist(`dummy',1,0) | missing(`dummy') | `samplevar' == 0
			if _rc {
				noi di as error "{phang}In the difference in differnce regression for outputvar [`outputvar'], the dummy [`dummy'] is not a real dummy as it has values differnt from 1 and 0. See tab below. The tab is restricted to the observations that are not excluded due to missing values etc. in the difference in differnce regression.{p_end}""
				noi tab `dummy' if `samplevar' == 1, missing
				error 480
			}
		}

		**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.

		*Test that there is some observations in each group
		forvalues tmt01 = 0/1 {
			forvalues t01 = 0/1 {

				*Summary stats on this group
				qui count if `treat' == `t01' & `time' == `tmt01' & `samplevar' == 1

				//There got to be more than 1 observation in each group for the regression to make sense
				if `r(N)' < 2 {
					noi di as error "{phang}In the difference in differnce regression for outputvar [`outputvar'] there were not enough observations in each combination of treatment [`treat'] and time [`time']. The tab below is restricted to the observations that are not excluded due to missing values etc. in the difference in differnce regression.{p_end}""
					noi tab `treat' `time' if `samplevar' == 1, missing
					error 480

				}
			}
		}

	end

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

	Write sub-commands for stats

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

*Sets up template for the result matrix
cap program drop 	templateResultMatrix
	program define	templateResultMatrix, rclass

	*Set the names of the different columns in the result Matrix
	local 2ndDiff_cols 			2D 2D_err 2D_stars 2D_N

	local 1stDiff_C_cols		1DC 1DC_err 1DC_stars 1DC_N
	local 1stDiff_T_cols		1DT 1DT_err 1DT_stars 1DT_N

	local basicMean_C0_cols		C0_mean C0_err C0_N
	local basicMean_T0_cols		T0_mean T0_err T0_N
	local basicMean_C1_cols		C1_mean C1_err C1_N
	local basicMean_T1_cols		T1_mean T1_err T1_N

	local colnames `2ndDiff_cols' `1stDiff_C_cols' `1stDiff_T_cols' `basicMean_C0_cols' `basicMean_T0_cols' `basicMean_C1_cols' `basicMean_T0_cols'

	*Define default row here. The results for each var will be one row that starts with all missing vlaues
	mat startRow = (.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.)
	mat colnames startRow = `colnames'

	return matrix startRow startRow
	return local colnames `colnames'

end

*Take the significance levels and count number of starts
cap program drop 	countStars
	program define	countStars, rclass

	args pvalue star1 star2 star3

	local stars 0
	foreach star_p_level in `star1' `star2' `star3' {

		if `pvalue' < `star_p_level' local ++stars
	}

	return local stars `stars'

end

**Convert the errors to the display stats picked
* by the user. Standard errors is the default.
cap program drop 	convertErrs
	program define	convertErrs, rclass

	args se_err N errortype

	*Test if custom star levels are used
	if "`errortype'" == "sd" {
		local err = `se_err' * sqrt(`N')
	}
	else {
		//For se keep se, for errhide keep se as matrix must have some value even if it will not be used
		local err = `se_err'
	}

	return local converted_error `err'

end

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

	Write sub-commands for outputs

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

	/******
	The result matrix can be passed into subcommands that output in either Excel, LaTeX or in the main window.

	The name of the result matrix is ddtab_resultMap. It can be refernced like this ddtab_resultMap[row, col] where
	row is the variable order where 1 is the first varaible in the varlist and col is the name of the stat.

	You always must make it first in to a 1x1 matrix, and then make that a local.

	*/

	*The results can be accessed like this, which makes the sub-commands less sensitive to changing column order in the section above.
	//mat A = ddtab_resultMap[3, "C0_Mean"] // returns a 1x1 matrix with the baseline mean for the countrol grop for the thrid outcome var
	//local a = el(A,1,1)				// returns the value

	//matlist A
	//di `a'

	/*
		Column name dictionary
			Differences:
			- 2D : Second differnce coefficient (t*tmt == 1)
			- 1DC : First  differnce coefficient control (t == 0)
			- 1DT : First  differnce coefficient treatment (tmt == 0)

			for each coefficent these stats are also provided:
				- _err : Second differnce errors (type of errors is set in command errortype)
				- _stars :  Second Differene - The number of significance stars (sig level set in command)
				- _N : Second Difference - Number of observtions in the regression

			Group means:
			- C0 - Control time 0
			- T0 - Treatment time 0
			- C1 - Control time 1
			- T1 - Treatment time 1

			for each group these stats are also provided:
				- _mean : the mean of the group
				- _err : the error in the mean (type of errors is set in command errortype)
				- _N : number of observations in baseline means

	*/

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

		Output table in result window

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

	cap program drop 	outputwindow
		program define	outputwindow

		syntax varlist , ddtab_resultMap(name) labmaxlen(numlist) rwlbls(string) starlevels(string) diformat(string) [covariates(string) errhide sd se]

		*Prepare lables for the erorrs to be displayed (in case any)
		if "`sd'" != "" local errlabel "SD"
		if "`se'" != "" local errlabel "SE"

		*Count numbers of variables to loop over
		local numVars = `:word count `varlist''

		*List of variabls to display and loop over when formatting
		local statlist 2D 1DT 1DC C0_mean T0_mean 2D_err 1DT_err 1DC_err C0_err T0_err 2D_N 1DT_N 1DC_N C0_N T0_N

		*************************
		* Table width for label column

		local first_hhline = 2 + `labmaxlen'
		local first_col = 4 + `labmaxlen'

		*************************
		* Table width for basline columns

		local bsln_space = 2
		local bsln_stat_left = `bsln_space' + 1
		local bsln_width = ((`bsln_space' * 2) + 8)

		*************************
		* Table width for first difference column

		local diff_space = 3
		local diff_stat_left = `diff_space' + 1
		local diff_width = ((`diff_space' * 2) + 10)

		*************************
		* Table width control column

		local ctrl_hline = `bsln_width' + 1 + `diff_width'
		local ctrl_space = (`ctrl_hline' - 7) / 2

		*************************
		* Table width treatment column

		local tmt_hline = `bsln_width' + 1 + `diff_width'
		local tmt_space = (`tmt_hline' - 9) / 2

		*************************
		* Table width diff diff column

		local didi_stat_left = 4
		local diffdiff_width  = 17

		*************************
		* Calculate stats column indexes

		local bsln_c_col	= `first_col'  + `bsln_width' + 1
		local diff_c_col	= `bsln_c_col' + `diff_width' + 1
		local bsln_t_col	= `diff_c_col' + `bsln_width' + 1
		local diff_t_col	= `bsln_t_col' + `diff_width' + 1
		local didi_col		= `diff_t_col' + `diffdiff_width' + 1

		*************************
		* Start writing table

		*Three title rows
		noi di as text "{c TLC}{hline `first_hhline'}{c TT}{hline `ctrl_hline'}{c TT}{hline `tmt_hline'}{c TT}{hline 17}{c TRC}"
		noi di as text "{c |}{col `first_col'}{c |}{dup `ctrl_space': }Control{dup `ctrl_space': }{c |}{dup `tmt_space': }Treatment{dup `tmt_space': }{c |}  Difference-in  {c |}"
		noi di as text "{c |}{col `first_col'}{c |}{dup `bsln_space': }Baseline{dup `bsln_space': }{c |}{dup `diff_space': }Difference{dup `diff_space': }{c |}{dup `bsln_space': }Baseline{dup `bsln_space': }{c |}{dup `diff_space': }Difference{dup `diff_space': }{c |}   -difference   {c |}"

		*Stats titels, show the stats displayed for each column in the order they are displayed
		noi di as text "{c |}{col `first_col'}{c |}{dup `bsln_stat_left': } Mean{col `bsln_c_col'}{c |}{dup `diff_stat_left': } Coef{col `diff_c_col'}{c |}{dup `bsln_stat_left': } Mean{col `bsln_t_col'}{c |}{dup `diff_stat_left': } Coef{col `diff_t_col'}{c |}{dup `didi_stat_left': } Coef{col `didi_col'}{c |}"
		if "`errhide'" == "" {
			noi di as text "{c |}{col `first_col'}{c |}{dup `bsln_stat_left': }(`errlabel'){col `bsln_c_col'}{c |}{dup `diff_stat_left': }(`errlabel'){col `diff_c_col'}{c |}{dup `bsln_stat_left': }(`errlabel'){col `bsln_t_col'}{c |}{dup `diff_stat_left': }(`errlabel'){col `diff_t_col'}{c |}{dup `didi_stat_left': }(`errlabel'){col `didi_col'}{c |}"
		}
		noi di as text "{c |}{col 3}Variable{col `first_col'}{c |}{dup `bsln_stat_left': } N{col `bsln_c_col'}{c |}{dup `diff_stat_left': } N{col `diff_c_col'}{c |}{dup `bsln_stat_left': } N{col `bsln_t_col'}{c |}{dup `diff_stat_left': } N{col `diff_t_col'}{c |}{dup `didi_stat_left': } N{col `didi_col'}{c |}"

		*Bottom row to table header
		noi di as text "{c LT}{hline `first_hhline'}{c +}{hline `bsln_width'}{c +}{hline `diff_width'}{c +}{hline `bsln_width'}{c +}{hline `diff_width'}{c +}{hline 17}{c RT}"

		*Loop over each variable and prepare the row
		forvalues row = 1/`numVars' {

			*Get lables from the list of lables previosly prepared
			local rwlbls = trim(subinstr("`rwlbls'", "@@","", 1))
			gettoken label rwlbls : rwlbls, parse("@@")

			*Loop over all the stats for this variable
			foreach stat of local statlist {

				**Run sub command that gets value from matrix and prepares it
				* in the format suitable for the result window table (and adding
				* stars if applicable)
				windowdiformat , statname("`stat'") row(`row') ddtab_resultMap(ddtab_resultMap) diformat("`diformat'") bslnw(`bsln_width') diffw(`diff_width') ddw(`diffdiff_width')

				*The main stat
				local `stat' `r(disp_stata)'

				*The number of spaces before the stat in the colum
				local `stat'_space = `r(disp_pre_space)'
			}

			*Disaplay each variable row at the same time
			noi di as text "{c |} `label'{col `first_col'}{c |}{dup `C0_mean_space': }`C0_mean'{dup `1DC_space': }`1DC'{dup `T0_mean_space': }`T0_mean'{dup `1DT_space': }`1DT'{dup `2D_space': }`2D'"

			*Unless error type is errhide, show the errors on a seperate row
			if "`errhide'" == "" {
				noi di as text "{c |}{col `first_col'}{c |}{dup `C0_err_space': }`C0_err'{dup `1DC_err_space': }`1DC_err'{dup `T0_err_space': }`T0_err'{dup `1DT_err_space': }`1DT_err'{dup `2D_err_space': }`2D_err'"
			}

			*The number of observations are shown on a separate row
			noi di as text "{c |}{col `first_col'}{c |}{dup `C0_N_space': }`C0_N'{dup `1DC_N_space': }`1DC_N'{dup `T0_N_space': }`T0_N'{dup `1DT_N_space': }`1DT_N'{dup `2D_N_space': }`2D_N'"

		}

		*Add bottom notes to the table
		noi di as text "{c BLC}{hline `first_hhline'}{c BT}{hline `bsln_width'}{c BT}{hline `diff_width'}{c BT}{hline `bsln_width'}{c BT}{hline `diff_width'}{c BT}{hline 17}{c BRC}"

		*************************
		* Write notes below the table

		*Show stars levels
		local star1_value : word 1 of `starlevels'
		local star2_value : word 2 of `starlevels'
		local star3_value : word 3 of `starlevels'
		noi di as text "  ***, **, and * indicate significance at the `star3_value', `star2_value', and `star1_value' percent critical level. "

		*List covariates used
		if ("`covariates'" != "") {
			noi di as text "  The following variable(s) was included as covariates [`covariates']"
		}

	end

cap program drop 	windowdiformat
	program define	windowdiformat, rclass

	syntax , statname(string) row(numlist) ddtab_resultMap(name) diformat(string)  bslnw(numlist) diffw(numlist) ddw(numlist)

		local numSpace 0

		mat temp = ddtab_resultMap[`row', "`statname'"]
		local `statname' = el(temp,1,1)

		if substr("`statname'", -2,.) == "_N" {
			local `statname'	: display %9.0f ``statname''
		}
		else {
			local `statname' 	: display `diformat' ``statname''
		}

		*Trime spaces on left from left.
		local `statname' = ltrim("``statname''")

		*For coefficients, add stars if applicable
		if inlist("`statname'", "2D", "1DT", "1DC") {

			mat starNumMat = ddtab_resultMap[`row', "`statname'_stars"]
			local starNum = el(starNumMat,1,1)

			if `starNum' == 0 local `statname' "``statname''    "
			if `starNum' == 1 local `statname' "``statname''*   "
			if `starNum' == 2 local `statname' "``statname''**  "
			if `starNum' == 3 local `statname' "``statname''*** "
		}

		*Add brackets to errors
		if inlist("`statname'", "2D_err", "1DT_err", "1DC_err", "C0_err", "T0_err") {
			local `statname' "(``statname'')"
		}

		*Get the lengt of the characters to display
		local len = strlen("``statname''")

		*Which column for this stat
		local colName = substr("`statname'", 1, 2)

		*Get corresponding width for that col
		if "`colName'" == "C0" local colw = `bslnw'
		if "`colName'" == "T0" local colw = `bslnw'
		if "`colName'" == "1D" local colw = `diffw'
		if "`colName'" == "2D" local colw = `ddw'

		* Calculate the number of spaces needed bofore
		* the value and add spaces after it
		if inlist("`statname'", "C0_mean", "T0_mean", "C0_N", "T0_N") {
			*Baseline mean values
			return local disp_stata "``statname''  {c |}"
			local numSpace = `colw' - `len' - 2
		}
		else if inlist("`statname'", "C0_err", "T0_err") {
			*Baseline mean values errors
			return local disp_stata "``statname'' {c |}"
			local numSpace = `colw' - `len' - 1
		}
		else if inlist("`statname'", "1DT", "1DC", "2D") {
			*First difference coefficent
			return local disp_stata "``statname''{c |}"
			local numSpace = `colw' - `len'
		}
		else if inlist("`statname'", "1DT_N", "1DC_N", "2D_N") {
			*First difference coefficent
			return local disp_stata "``statname''    {c |}"
			local numSpace = `colw' - `len' - 4
		}
		else if inlist("`statname'", "1DT_err", "1DC_err", "2D_err")  {
			*First difference coefficient error
			return local disp_stata "``statname''   {c |}"
			local numSpace = `colw' - `len' - 3
		}

		**If numbers are so big that numSapce is negative, set it to 0 as
		* numSpace cannot be negative. Table will show incorrectly but
		* will display.
		if `numSpace' < 0 local numSpace 0

		return local disp_pre_space = `numSpace'
		return local disp_len = `len'

	end