query

query

*Clear and set directory;
	clear
	cd "C:\Users\rsanchez\Dropbox\Tesis_ITAM_RS"
*database query;
	use "tesisDB.dta"
	xtset id year

*Clean code
	keep id year hom_rate_riv conflicto_12 alianza_sinconf violentconflict niv_rezago_edu agresion_a_militares lnPIB ind_marginacion niv_pobreza mean_edu niv_sinprim niv_desempleo coef_gini tomasC Laboratorios erad_mar erad_pop Imar Icoca Iopi Border1 Border2 Border3 Border4 route PortGolfo PortPacifico eficiencia WEFICI hom_rate_riv SPATIALLAG co_count coca mar opi lab tomas e_mar e_pop estructura PrP15PRIM lnUnemployment code erad_marijuana tratamientosequiamar ttratamientosequiamar km2 dens_mar PR_Secuestro  S_Extorsion PR_Extorsion  S_Robo  PR_Robo  S_Allanamiento  PR_Allanamiento  poverty  S_Secuestro  port rivalry_homicide

*Variable construction;
	tabulate estructura, gen(e)

*Tabla 1) Parametrizacin de la violencia (Nivel Municipal)
	*Modelo 1
		xtpoisson hom_rate_riv lnPIB ind_marginacion niv_pobreza mean_edu niv_sinprim niv_desempleo coef_gini, pa corr(unstructured)
		*outreg2 using "***", replace title(Parametrizacin de violencia - Poisson) ctitle(Tasa Homicidios Relacionados)
	*Modelo 2
		xtpoisson hom_rate_riv tomasC Laboratorios erad_mar erad_pop coca mar opi Border1 Border2 Border3 Border4 route PortGolfo PortPacifico, pa corr(unstructured)
		*outreg2 using "***", append ctitle(tasa Homicidios Relacionados)
	*Modelo 3
		*Con rivalidad
		xtpoisson hom_rate_riv  lnPIB ind_marginacion niv_pobreza mean_edu niv_sinprim niv_desempleo coef_gini tomasC Laboratorios erad_mar erad_pop  Imar Icoca Iopi Border1 Border2 Border3 Border4 route PortGolfo PortPacifico, pa corr(unstructured)
		*outreg2 using "***", append ctitle(tasa Homicidios Relacionados)
	*Modelo 4
		*Con Lag
		xtpoisson hom_rate_riv  lnPIB ind_marginacion niv_pobreza mean_edu niv_sinprim niv_desempleo coef_gini tomasC Laboratorios erad_mar erad_pop  Imar Icoca Iopi Border1 Border2 Border3 Border4 route PortGolfo PortPacifico L.eficiencia L.WEFICI L.hom_rate_riv L.SPATIALLAG, pa corr(unstructured)
		*outreg2 using "***", append ctitle(tasa Homicidios Relacionados)

*Tabla 2) Anlisis de la competencia - *estructura control cluster municipal socioeconmico usarlo?
	*Modelo 5  - **con corr unstructured no se logra convergencia
		xtpoisson co_count  Border1 Border2 Border3 Border4 route PortGolfo PortPacifico Icoca Imar Iopi Laboratorios tomasC erad_mar erad_pop  e1 e2 e3, re
		*outreg2 using 2.doc, replace title(Causas de competencia)
	*Modelo 6  - **con corr unstructured no se logra convergencia
		xtpoisson co_count Border1 Border2 Border3 Border4 route PortGolfo PortPacifico coca mar opi lab tomas e_mar e_pop e1 e2 e3, re
		*outreg2 using 2.doc, append ctitle(Competencia con Dummy)
	*Modelo 7
		xtlogit conflicto_12 Border1 Border2 Border3 Border4 route PortGolfo PortPacifico coca mar opi lab tomas e_mar e_pop e1 e2 e3, pa corr(unstructured)

		d*outreg2 using 2.doc, append ctitle(Conflicto)
	*Modelo 8
		xtlogit alianza_sinconf Border1 Border2 Border3 Border4 route PortGolfo PortPacifico coca mar opi lab tomas e_mar e_pop e1 e2 e3, pa corr(unstructured)
		*outreg2 using 2.doc, append ctitle(Alianza_NC)
	*Modelo 9
		xtlogit  violentconflict Border1 Border2 Border3 Border4 route PortGolfo PortPacifico coca mar opi lab tomas e_mar e_pop e1 e2 e3 if alianza_sinconf==0 , pa corr(unstructured)
		*outreg2 using 2.doc, append ctitle(Conflicto Violento)
	*Modelo 10
		xtpoisson agresion_a_militares Border1 Border2 Border3 Border4 route PortGolfo PortPacifico coca mar opi lab tomas e_mar e_pop e1 e2 e3, pa corr(unstructured)
		*outreg2 using 2.doc, append ctitle(agresion_a_militares)
	*Modelo 11	*homicidios con control de municipios.
		xtpoisson hom_rate_riv Border1 Border2 Border3 Border4 route PortGolfo PortPacifico coca mar opi lab tomas e_mar e_pop e1 e2 e3, pa corr(unstructured)

***********************************;
********Anlisis de cluster********;
clear
use "tesisDB.dta"
xtset code2 year
	*-se realiz con ao base 2010-
	keep if year==2010

*1) Clusterizacin Socioeconmica -Wardslinkage-;
	cluster wardslinkage lnPIB PrP15PRIM mean_edu lnUnemployment coef_gini, measure(L2) name(cluster1)
	cluster dendrogram cluster1, cutnumber(10)
	cluster generate estructura_= groups(3), name(cluster1) ties(error)
	drop cluster1_id cluster1_ord cluster1_hgt
	*tabstat PIB Unemployment mean_edu inequality if year==2008, statistics( mean var median ) by(estructura) columns(variables)

*2) Clusterizacin sobre violencia e impunidad -Wardslinkage-;
	cluster  wardslinkage  LWhom_rate_riv Lhom_rate_riv Leficiencia LWeficiencia, measure(L2) name(cluster6)
	cluster dendrogram cluster6, cutnumber(5)
	cluster generate categoriaviolencia2= groups(3), name(cluster6) ties(error)
	table categoriaviolencia
		*re-ordenamiento por nivel de violencia;
		replace categoriaviolencia=4 if categoriaviolencia==1
		replace categoriaviolencia=1 if categoriaviolencia==2
		replace categoriaviolencia=2 if categoriaviolencia==4
		table categoriaviolencia
		drop cluster5_id cluster5_ord cluster5_hgt

***********************************;
***************Anexo 1*************;
	*Sequia (Quasi Experimental Method)
	******************
		*Anlsis de Diferencia en Diferencias (grupo tratamiento: sequia)-> con kernel Maching
		*Relies on the panel structure of the data (usually two periods: based line and follow up).
		*Control for unobservable and time invariant characteristics. Control for observable characteristics if available.
		*psm
		*Stata module
		ssc install diff
	******************
		global breps 100
		*global xlist estructura
		*global xlist lnPIB PrP15PRIM lnUnemployment  coef_gini  mean_edu  Border1 Border2 Border3 route PortPacifico
		global xlist lnPIB PrP15PRIM lnUnemployment ind_marginacion niv_sinprim niv_pobreza niv_rezago_edu coef_gini
		global xlist lnPIB PrP15PRIM mean_edu lnUnemployment coef_gini

	*Efecto de la sequia en la erradicacin de mariguana
		*Quantile diff in diff
		diff erad_marijuana, t(tratamientosequiamar) p(ttratamientosequiamar) cov($xlist) kernel rcs qdid(.5)
		diff erad_marijuana, t(tratamientosequiamar) p(ttratamientosequiamar) cov($xlist) id(code) kernel rcs
		diff erad_marijuana, t(tratamientosequiamar) p(ttratamientosequiamar)
			*Balancing - t test
			diff erad_marijuana, t(tratamientosequiamar) p(ttratamientosequiamar) cov($xlist)  test

		*Efecto de la sequia en la violencia
		diff hom_rate_riv, t(tratamientosequiamar) p(ttratamientosequiamar) cov($xlist) id(code) kernel rcs qdid(.5)
		diff hom_rate_riv, t(tratamientosequiamar) p(ttratamientosequiamar) cov($xlist) id(code) kernel rcs
		diff hom_rate_riv, t(tratamientosequiamar) p(ttratamientosequiamar)
			*Balancing - t test
			diff hom_rate_riv, t(tratamientosequiamar) p(ttratamientosequiamar) cov($xlist)  test

***********************************;
***************Anexo 3*************;
	*Efecto de la violencia en otros crmenes  (Mtodo de Variables instrumentales)
	******************
		*Se instrumentaliza utilizando las principales variables de posicin geogrfica del municipio
		*Para obtener un estimador consistente mediante el mtodo de variables instrumentales se deben cumplir dos condiciones.
		*1) Relevancia del instrumento con nuestra variable de inters (Cov(Homicidios Relacionados, Zi)).
		*2) Exogeneidad o restriccin de exclusin: que el instrumento no est correlacionado con el error (Cov(Ui,Zi)=0).
	******************
	xtivreg S_Secuestro  poverty lnPIB PrP15PRIM lnUnemployment coef_gini mean_edu  tomasC  (rivalry_homicide = Border1 Border2 Border3 route port), re
	*outreg2 using instrumento.doc, replace title(Instrumentos) ctitle(S_Secuestro)
	xtivreg PR_Secuestro  poverty lnPIB PrP15PRIM lnUnemployment coef_gini mean_edu  tomasC  (rivalry_homicide = Border1 Border2 Border3 route port), re
	*outreg2 using instrumento.doc, append ctitle(PR_Secuestro)
	xtivreg S_Extorsion  poverty lnPIB PrP15PRIM lnUnemployment coef_gini mean_edu  tomasC  (rivalry_homicide = Border1 Border2 Border3 route port), re
	*outreg2 using instrumento.doc, append  ctitle(S_Extorsion)
	xtivreg PR_Extorsion  poverty lnPIB PrP15PRIM lnUnemployment coef_gini mean_edu  tomasC  (rivalry_homicide = Border1 Border2 Border3 route port), re
	*outreg2 using instrumento.doc, append ctitle(PR_Extorsion)
	xtivreg S_Robo  poverty lnPIB PrP15PRIM lnUnemployment coef_gini mean_edu  tomasC  (rivalry_homicide = Border1 Border2 Border3 route port), re
	*outreg2 using instrumento.doc, append ctitle(S_Robo)
	xtivreg PR_Robo  poverty lnPIB PrP15PRIM lnUnemployment coef_gini mean_edu  tomasC  (rivalry_homicide = Border1 Border2 Border3 route port), re
	*outreg2 using instrumento.doc, append ctitle(PR_Robo)
	xtivreg S_Allanamiento  poverty lnPIB PrP15PRIM lnUnemployment coef_gini mean_edu  tomasC  (rivalry_homicide = Border1 Border2 Border3 route port), re
	*outreg2 using instrumento.doc, append ctitle(S_Allanamiento)
	xtivreg PR_Allanamiento  poverty lnPIB PrP15PRIM lnUnemployment coef_gini mean_edu  tomasC  (rivalry_homicide = Border1 Border2 Border3 route port), re
	*outreg2 using instrumento.doc, append ctitle(PR_Allanamiento)

*Clear and set directory;
	clear
	cd "C:\Users\rsanchez\Dropbox\Tesis_ITAM_RS"
*database query;
	use "tesisDB.dta"
	xtset id year

clear
cd "C:\Users\rsanchez\Dropbox\tesis\Anlisis\tesiscompu"
use "Limpia2.dta"
xtset id year
*Clean code
	keep id year hom_rate_riv conflicto_12 alianza_sinconf violentconflict niv_rezago_edu agresion_a_militares lnPIB ind_marginacion niv_pobreza mean_edu niv_sinprim niv_desempleo coef_gini tomasC Laboratorios erad_mar erad_pop Imar Icoca Iopi Border1 Border2 Border3 Border4 route PortGolfo PortPacifico eficiencia WEFICI hom_rate_riv SPATIALLAG co_count coca mar opi lab tomas e_mar e_pop estructura PrP15PRIM lnUnemployment code erad_marijuana tratamientosequiamar ttratamientosequiamar km2 dens_mar PR_Secuestro  S_Extorsion PR_Extorsion  S_Robo  PR_Robo  S_Allanamiento  PR_Allanamiento  poverty  S_Secuestro  port rivalry_homicide
	save "C:\Users\rsanchez\Dropbox\Tesis_ITAM_RS\tesisDB.dta", replace

*Variable construction;
	tabulate estructura, gen(e)

*Tabla 1) Parametrizacin de la violencia (Nivel Municipal)
	*Modelo 1
		xtpoisson hom_rate_riv lnPIB ind_marginacion niv_pobreza mean_edu niv_sinprim niv_desempleo coef_gini, pa corr(unstructured)
		*outreg2 using "***", replace title(Parametrizacin de violencia - Poisson) ctitle(Tasa Homicidios Relacionados)
	*Modelo 2
		xtpoisson hom_rate_riv tomasC Laboratorios erad_mar erad_pop coca mar opi Border1 Border2 Border3 Border4 route PortGolfo PortPacifico, pa corr(unstructured)
		*outreg2 using "***", append ctitle(tasa Homicidios Relacionados)
	*Modelo 3
		*Con rivalidad
		xtpoisson hom_rate_riv  lnPIB ind_marginacion niv_pobreza mean_edu niv_sinprim niv_desempleo coef_gini tomasC Laboratorios erad_mar erad_pop  Imar Icoca Iopi Border1 Border2 Border3 Border4 route PortGolfo PortPacifico, pa corr(unstructured)
		*outreg2 using "***", append ctitle(tasa Homicidios Relacionados)
	*Modelo 4
		*Con Lag
		xtpoisson hom_rate_riv  lnPIB ind_marginacion niv_pobreza mean_edu niv_sinprim niv_desempleo coef_gini tomasC Laboratorios erad_mar erad_pop  Imar Icoca Iopi Border1 Border2 Border3 Border4 route PortGolfo PortPacifico L.eficiencia L.WEFICI L.hom_rate_riv L.SPATIALLAG, pa corr(unstructured)
		*outreg2 using "***", append ctitle(tasa Homicidios Relacionados)

*Tabla 2) Anlisis de la competencia - *estructura control cluster municipal socioeconmico usarlo?
	*Modelo 5  - **con corr unstructured no se logra convergencia
		xtpoisson co_count  Border1 Border2 Border3 Border4 route PortGolfo PortPacifico Icoca Imar Iopi Laboratorios tomasC erad_mar erad_pop  e1 e2 e3, re
		*outreg2 using 2.doc, replace title(Causas de competencia)
	*Modelo 6  - **con corr unstructured no se logra convergencia
		xtpoisson co_count Border1 Border2 Border3 Border4 route PortGolfo PortPacifico coca mar opi lab tomas e_mar e_pop e1 e2 e3, re
		*outreg2 using 2.doc, append ctitle(Competencia con Dummy)
	*Modelo 7
		xtlogit conflicto_12 Border1 Border2 Border3 Border4 route PortGolfo PortPacifico coca mar opi lab tomas e_mar e_pop e1 e2 e3, pa corr(unstructured)

		d*outreg2 using 2.doc, append ctitle(Conflicto)
	*Modelo 8
		xtlogit alianza_sinconf Border1 Border2 Border3 Border4 route PortGolfo PortPacifico coca mar opi lab tomas e_mar e_pop e1 e2 e3, pa corr(unstructured)
		*outreg2 using 2.doc, append ctitle(Alianza_NC)
	*Modelo 9
		xtlogit  violentconflict Border1 Border2 Border3 Border4 route PortGolfo PortPacifico coca mar opi lab tomas e_mar e_pop e1 e2 e3 if alianza_sinconf==0 , pa corr(unstructured)
		*outreg2 using 2.doc, append ctitle(Conflicto Violento)
	*Modelo 10
		xtpoisson agresion_a_militares Border1 Border2 Border3 Border4 route PortGolfo PortPacifico coca mar opi lab tomas e_mar e_pop e1 e2 e3, pa corr(unstructured)
		*outreg2 using 2.doc, append ctitle(agresion_a_militares)
	*Modelo 11	*homicidios con control de municipios.
		xtpoisson hom_rate_riv Border1 Border2 Border3 Border4 route PortGolfo PortPacifico coca mar opi lab tomas e_mar e_pop e1 e2 e3, pa corr(unstructured)

***********************************;
********Anlisis de cluster********;
clear
use "tesisDB.dta"
xtset code2 year
	*-se realiz con ao base 2010-
	keep if year==2010

*1) Clusterizacin Socioeconmica -Wardslinkage-;
	cluster wardslinkage lnPIB PrP15PRIM mean_edu lnUnemployment coef_gini, measure(L2) name(cluster1)
	cluster dendrogram cluster1, cutnumber(10)
	cluster generate estructura_= groups(3), name(cluster1) ties(error)
	drop cluster1_id cluster1_ord cluster1_hgt
	*tabstat PIB Unemployment mean_edu inequality if year==2008, statistics( mean var median ) by(estructura) columns(variables)

*2) Clusterizacin sobre violencia e impunidad -Wardslinkage-;
	cluster  wardslinkage  LWhom_rate_riv Lhom_rate_riv Leficiencia LWeficiencia, measure(L2) name(cluster6)
	cluster dendrogram cluster6, cutnumber(5)
	cluster generate categoriaviolencia2= groups(3), name(cluster6) ties(error)
	table categoriaviolencia
		*re-ordenamiento por nivel de violencia;
		replace categoriaviolencia=4 if categoriaviolencia==1
		replace categoriaviolencia=1 if categoriaviolencia==2
		replace categoriaviolencia=2 if categoriaviolencia==4
		table categoriaviolencia
		drop cluster5_id cluster5_ord cluster5_hgt

***********************************;
***************Anexo 1*************;
	*Sequia (Quasi Experimental Method)
	******************
		*Anlsis de Diferencia en Diferencias (grupo tratamiento: sequia)-> con kernel Maching
		*Relies on the panel structure of the data (usually two periods: based line and follow up).
		*Control for unobservable and time invariant characteristics. Control for observable characteristics if available.
		*psm
		*Stata module
		ssc install diff
	******************
		global breps 100
		*global xlist estructura
		*global xlist lnPIB PrP15PRIM lnUnemployment  coef_gini  mean_edu  Border1 Border2 Border3 route PortPacifico
		global xlist lnPIB PrP15PRIM lnUnemployment ind_marginacion niv_sinprim niv_pobreza niv_rezago_edu coef_gini
		global xlist lnPIB PrP15PRIM mean_edu lnUnemployment coef_gini

	*Efecto de la sequia en la erradicacin de mariguana
		*Quantile diff in diff
		diff erad_marijuana, t(tratamientosequiamar) p(ttratamientosequiamar) cov($xlist) kernel rcs qdid(.5)
		diff erad_marijuana, t(tratamientosequiamar) p(ttratamientosequiamar) cov($xlist) id(code) kernel rcs
		diff erad_marijuana, t(tratamientosequiamar) p(ttratamientosequiamar)
			*Balancing - t test
			diff erad_marijuana, t(tratamientosequiamar) p(ttratamientosequiamar) cov($xlist)  test

		*Efecto de la sequia en la violencia
		diff hom_rate_riv, t(tratamientosequiamar) p(ttratamientosequiamar) cov($xlist) id(code) kernel rcs qdid(.5)
		diff hom_rate_riv, t(tratamientosequiamar) p(ttratamientosequiamar) cov($xlist) id(code) kernel rcs
		diff hom_rate_riv, t(tratamientosequiamar) p(ttratamientosequiamar)
			*Balancing - t test
			diff hom_rate_riv, t(tratamientosequiamar) p(ttratamientosequiamar) cov($xlist)  test

***********************************;
***************Anexo 3*************;
	*Efecto de la violencia en otros crmenes  (Mtodo de Variables instrumentales)
	******************
		*Se instrumentaliza utilizando las principales variables de posicin geogrfica del municipio
		*Para obtener un estimador consistente mediante el mtodo de variables instrumentales se deben cumplir dos condiciones.
		*1) Relevancia del instrumento con nuestra variable de inters (Cov(Homicidios Relacionados, Zi)).
		*2) Exogeneidad o restriccin de exclusin: que el instrumento no est correlacionado con el error (Cov(Ui,Zi)=0).
	******************
	xtivreg S_Secuestro  poverty lnPIB PrP15PRIM lnUnemployment coef_gini mean_edu  tomasC  (rivalry_homicide = Border1 Border2 Border3 route port), re
	*outreg2 using instrumento.doc, replace title(Instrumentos) ctitle(S_Secuestro)
	xtivreg PR_Secuestro  poverty lnPIB PrP15PRIM lnUnemployment coef_gini mean_edu  tomasC  (rivalry_homicide = Border1 Border2 Border3 route port), re
	*outreg2 using instrumento.doc, append ctitle(PR_Secuestro)
	xtivreg S_Extorsion  poverty lnPIB PrP15PRIM lnUnemployment coef_gini mean_edu  tomasC  (rivalry_homicide = Border1 Border2 Border3 route port), re
	*outreg2 using instrumento.doc, append  ctitle(S_Extorsion)
	xtivreg PR_Extorsion  poverty lnPIB PrP15PRIM lnUnemployment coef_gini mean_edu  tomasC  (rivalry_homicide = Border1 Border2 Border3 route port), re
	*outreg2 using instrumento.doc, append ctitle(PR_Extorsion)
	xtivreg S_Robo  poverty lnPIB PrP15PRIM lnUnemployment coef_gini mean_edu  tomasC  (rivalry_homicide = Border1 Border2 Border3 route port), re
	*outreg2 using instrumento.doc, append ctitle(S_Robo)
	xtivreg PR_Robo  poverty lnPIB PrP15PRIM lnUnemployment coef_gini mean_edu  tomasC  (rivalry_homicide = Border1 Border2 Border3 route port), re
	*outreg2 using instrumento.doc, append ctitle(PR_Robo)
	xtivreg S_Allanamiento  poverty lnPIB PrP15PRIM lnUnemployment coef_gini mean_edu  tomasC  (rivalry_homicide = Border1 Border2 Border3 route port), re
	*outreg2 using instrumento.doc, append ctitle(S_Allanamiento)
	xtivreg PR_Allanamiento  poverty lnPIB PrP15PRIM lnUnemployment coef_gini mean_edu  tomasC  (rivalry_homicide = Border1 Border2 Border3 route port), re
	*outreg2 using instrumento.doc, append ctitle(PR_Allanamiento)


0829 in to.do

0829 in to.do

= to.do: =

  o bloggish directories should have a "make wc" target that subtracts the word count of
    the template file.  Or, better, use sed to filter out tags.

  o bootstrap should check ~/.ssh to see whether to use savitzky.net or github.

========================================================================================>
Work Log:
========

2015:
=====

1111We
  @ OpenSSH/Cookbook/Multiplexing - Wikibooks
    Makes ssh much faster, and circumvents dreamhost's connection limits.
    > mkdir ~/.ssh/controlmasters; chmod 700 ~/.ssh/controlmasters
  * Add the following to .ssh/config, in the global section at the top:
      ControlPath ~/.ssh/controlmasters/%r@%h:%p
      ControlPersist 10m
      ControlMaster auto
  @ https://github.com/blipvert/ljupdate/commits/master marginally more up to date
    * update emacs/depends.make

2016:
=====

0214Su
  * much hacking in gnome-setup and font setup over the last week or so.

0215Mo
  * added adobe-source-code-pro font, tell emacs to use system font.

... Really ought to copy the config-related stuff out of starport/Admin/admin.to.do

0626
  ~ alltray looked useful - lets you put an icon for any program into the tray.
    It starts the program if it's not already running, but fails in xmonad because it's
    waiting for the program to be iconified.
  * gsimplecal, fbpanel, and probably others have subdirectories in .config
    probably best is to make another directory called dotconfig, parallel to dotfiles

0627Mo
  * made the Makefiles independendent of Tools/Makefile.

0704Mo
  * git subtree add --prefix bin ../bin master
  * The idea is that if there's a pre-existing ~/bin, we can symlink into it.

0705Tu
  * regular dotfiles should start with "_" rather than ".", to make them visible.
    -> move dotfiles/.* -> dotfiles/_*; update dotfiles/Makefile

0716Sa
  . Some dotfiles may need to be modified by a script rather than simply symlinked.
    That's because things like username and email address change from one system to
    another.  In most cases, though, one can use include files generated by make install.

0719Tu
  * When site-dependent parameters can be in separate files (include files/modules).
    the various install targets can initialize them from templates.  A good place to start
    would be .xmonad/Local.hs.  Could also do this for .bashrc; a conditional include
    would make it unnecessary to generate the file if it's not needed. (0716)
    : for gitconfig - note that the file doesn't need to exist
      [include]
	  path = /path/to/file

0725Mo
  * color-coded workspace labels.  ws N makes an xclock with WS=N and the appropriate
    resistor color code.
  * the ability to make ad-hoc workspace labels might help.  Put the list in a file that
    can be read in either xmonad or the bottom-bars script.  Possibly a top dbar with
    vertical menu. (0719) -> add a second argument to ws.
  * Re-running ws N should grep ps for the appropriate color code and kill it.
    An alternative to xclock would be dzen -p.

0726Tu
  x use dzen for workspace labels?  Note that dzen is smaller, but only slightly.
    Problem is that it doesn't seem possible to have it shrinkwrap text.
  * separate widths for first and other top bars; make default 950; adjust ws

0827Sa
  * Allow MakeStuff as well as Tools.  Eventually it will be possible to drop Tools as
    an alternative.

0828Su
  ^ Config -> Honu.  The only real question is whether I want to make Honu a separate
    version, cleaned up and generalized for distribution. -> I don't think so.  It would
    be hard to keep them in sync.  The main me-specific things are the link pages in web,
    and some of the stuff in Archive, but there are also some of the dotfiles (e.g.
    .signature and .Xdefaults-*), stuff in the emacs config, and...  On second thought: I
    think I'd be a very uncomfortable about putting .mailrc, .gnus, and the bookmarks out
    there.  So there's going to have to be a rewrite anyway.  Those can go in -Personal-
  ^ Problematic stuff -- bookmarks, .mailrc, .gnus, etc. belongs in a separate git repo
    that's a subdirectory of local!  Can of course have dotfiles and dotconfig subdirs.
    Can have its own bootstrap, which would get the user-specific out of there, too.  In
    fact, call it local/local-Config or local/My-Honu or some such and derive it from the
    original, with all the old history.  Make a relatively clean start for Honu.

0829Mo
  o bootstrap and the first run of make should log messages, and print out the log on
    exit.

========================================================================================>|
Local Variables:
    fill-column:90
End:

= to.do: =

  o bloggish directories should have a "make wc" target that subtracts the word count of
    the template file.  Or, better, use sed to filter out tags.

  o bootstrap should check ~/.ssh to see whether to use savitzky.net or github.

========================================================================================>
Work Log:
========

2015:
=====

1111We
  @ OpenSSH/Cookbook/Multiplexing - Wikibooks
    Makes ssh much faster, and circumvents dreamhost's connection limits.
    > mkdir ~/.ssh/controlmasters; chmod 700 ~/.ssh/controlmasters
  * Add the following to .ssh/config, in the global section at the top:
      ControlPath ~/.ssh/controlmasters/%r@%h:%p
      ControlPersist 10m
      ControlMaster auto
  @ https://github.com/blipvert/ljupdate/commits/master marginally more up to date
    * update emacs/depends.make

2016:
=====

0214Su
  * much hacking in gnome-setup and font setup over the last week or so.

0215Mo
  * added adobe-source-code-pro font, tell emacs to use system font.

... Really ought to copy the config-related stuff out of starport/Admin/admin.to.do

0626
  ~ alltray looked useful - lets you put an icon for any program into the tray.
    It starts the program if it's not already running, but fails in xmonad because it's
    waiting for the program to be iconified.
  * gsimplecal, fbpanel, and probably others have subdirectories in .config
    probably best is to make another directory called dotconfig, parallel to dotfiles

0627Mo
  * made the Makefiles independendent of Tools/Makefile.

0704Mo
  * git subtree add --prefix bin ../bin master
  * The idea is that if there's a pre-existing ~/bin, we can symlink into it.

0705Tu
  * regular dotfiles should start with "_" rather than ".", to make them visible.
    -> move dotfiles/.* -> dotfiles/_*; update dotfiles/Makefile

0716Sa
  . Some dotfiles may need to be modified by a script rather than simply symlinked.
    That's because things like username and email address change from one system to
    another.  In most cases, though, one can use include files generated by make install.

0719Tu
  * When site-dependent parameters can be in separate files (include files/modules).
    the various install targets can initialize them from templates.  A good place to start
    would be .xmonad/Local.hs.  Could also do this for .bashrc; a conditional include
    would make it unnecessary to generate the file if it's not needed. (0716)
    : for gitconfig - note that the file doesn't need to exist
      [include]
	  path = /path/to/file

0725Mo
  * color-coded workspace labels.  ws N makes an xclock with WS=N and the appropriate
    resistor color code.
  * the ability to make ad-hoc workspace labels might help.  Put the list in a file that
    can be read in either xmonad or the bottom-bars script.  Possibly a top dbar with
    vertical menu. (0719) -> add a second argument to ws.
  * Re-running ws N should grep ps for the appropriate color code and kill it.
    An alternative to xclock would be dzen -p.

0726Tu
  x use dzen for workspace labels?  Note that dzen is smaller, but only slightly.
    Problem is that it doesn't seem possible to have it shrinkwrap text.
  * separate widths for first and other top bars; make default 950; adjust ws

0827Sa
  * Allow MakeStuff as well as Tools.  Eventually it will be possible to drop Tools as
    an alternative.

0828Su
  ^ Config -> Honu.  The only real question is whether I want to make Honu a separate
    version, cleaned up and generalized for distribution. -> I don't think so.  It would
    be hard to keep them in sync.  The main me-specific things are the link pages in web,
    and some of the stuff in Archive, but there are also some of the dotfiles (e.g.
    .signature and .Xdefaults-*), stuff in the emacs config, and...  On second thought: I
    think I'd be a very uncomfortable about putting .mailrc, .gnus, and the bookmarks out
    there.  So there's going to have to be a rewrite anyway.  Those can go in -Personal-
  ^ Problematic stuff -- bookmarks, .mailrc, .gnus, etc. belongs in a separate git repo
    that's a subdirectory of local!  Can of course have dotfiles and dotconfig subdirs.
    Can have its own bootstrap, which would get the user-specific out of there, too.  In
    fact, call it local/local-Config or local/My-Honu or some such and derive it from the
    original, with all the old history.  Make a relatively clean start for Honu.

========================================================================================>|
Local Variables:
    fill-column:90
End:


iematch : Output table fomrat

iematch : Output table fomrat

Standardize format with thousand seperator

	cap program drop 	iematch
	    program define	iematch

		noi di "Command OK!"

		syntax  [if] [in]  , 					///
			GRPdummy(varname) 					///
			MATCHvar(varname) 					///
			[									///
			IDvar(varname)						///
			m1									///
			maxdiff(numlist max = 1 min = 1) 	///
			seedok						 		///
			MATCHIDname(string)					///
			MATCHDIffname(string)				///
			MATCHREsultname(string)				///
			MATCHCOuntname(string)				///
			]

		*****

		noi di "Syntax OK!"

		pause on

		qui {

		********************************
		*
		*	Gen temp sort and merge var
		*
		********************************

		tempvar originalSort ifinvar

		gen `originalSort' = _n

		preserve

*Testing input
if 1 {

			local obsexcludstring ""

			*Deal with if and in and display info.
			if "`if'`in'" != "" {

				gen `ifinvar' = 1 `if'`in'

				count if `ifinvar' != 1
				if `r(N)' > 0 {

					*This is not an error just outputting the number
					local obsexcludstring "`obsexcludstring'`r(N)' observation(s) were excluded in {inp:if}/{inp:in}: (`if'`in').{break}"

				}

				keep `if'`in'
			}

			********************************
			*
			*	Checking group dummy
			*
			********************************

			*Test that the group dummy is 1, 0 or missing
			cap assert inlist(`grpdummy', 1, 0, .) | `grpdummy' > .
			if _rc != 0 {

				di as error "{pstd}The variable in grpdummy(`grpdummy') is not a dummy variable. The variable is only allowed to have the values 1, 0 or missing. Observations with missing varaibles in the grpdummy are ignored by this command.{p_end}"
				error _rc
			}

			**Exclude obs with missing value in groupdummy

			*Count number of obs to be dropped and and output that number if more than zero
			count if missing(`grpdummy')
			if `r(N)' > 0 {

				*This is not an error just outputting the number
				local obsexcludstring  "`obsexcludstring'`r(N)' observation(s) were excluded due to missing value in  grpdummy(`grpdummy').{break}"
			}
			*Drop obs with missing
			drop if missing(`grpdummy')

			********************************
			*
			*	Checking match continous var
			*
			********************************

			*Test that the continous is numeric
			cap confirm numeric variable `matchvar'
			if _rc != 0 {

				noi di as error "{pstd}The variable to match on specified in matchvar(`matchvar') is not a numeric variable.{p_end}"
				error 109

			}

			**All variables with value 1 or 0 in the group dummy and
			* not excluded by if/in must have a value in matchvar
			count if missing(`matchvar')
			if `r(N)' > 0 {
				local obsexcludstring  "`obsexcludstring'`r(N)' observation(s) were excluded due to missing value in matchvar(`matchvar').{break}"

			}
			*Drop obs with missing
			drop if missing(`matchvar')

			********************************
			*
			*	Checking match var and group dummy are unique
			*
			********************************

			if "`seedok'" == "" {

				**test that there are no duplicates in match
				* var within each type of observation
				cap isid `matchvar' `grpdummy'

				if _rc != 0 {

					noi di as error "{pstd}There are base observations or target observations {...}"
					noi di as error "with duplicate values in matchvar(`matchvar'). To guarantee {...}"
					noi di as error "a replicable match you must {help seed:set a seed}. To supress {...}"
					noi di as error "this error message after you have set a the seed, or if a {...}"
					noi di as error "replicable match is not important to you, use option {inp:seedok}{p_end}"
					error 198

				}
			}

			********************************
			*
			*	Checking that there are more target
			*	obs than base obs in a 1-to-1 match
			*
			********************************

			if "`m1'" == "" {

				*Count number of base vars
				count if `grpdummy' == 1
				local numBaseObs `r(N)'

				*Count number of target vars
				count if `grpdummy' == 0
				local numTrgtObs `r(N)'

				*Test that there are more target
				cap assert `numTrgtObs' >= `numBaseObs'

				if _rc != 0 {

					noi di as error "{pstd}There are more base observations than target observations. This is not allowed in a one-to-one match. See option {inp:m1} for an alternaitve matching where it is allowed to have more base observations than target ovbservations.{p_end}"
					error _rc
				}
			}

			********************************
			*
			*	Checking duplicates in variable names in options
			*
			********************************

			*Create a local of all varnames used in any option
			local allnewvars `idvar' `matchidname' `matchdiffname' `matchresult'

			*Check if there are any duplicates in the local of all varnames in options
			local dupnewvars : list dups allnewvars

			*Throw error if there were any duplicates
			if "`dupnewvars'" != "" {

				di as error "{pstd}The same new variable name was used twice or more in the options generating a new variable. Go back and check syntax.{p_end}"
				error 198

			}

			********************************
			*
			*	Checking ID var
			*
			********************************

			*Checking set-up for the ID var used for _matchID
			if "`idvar'" == "" {

				*Copy this name
				local idvar _ID

				*Make sure that the default name _ID is not already used
				cap confirm variable `idvar'
				if _rc == 0 {

					di as error "{pstd}A variable with name `idvar' is already defined. Either drop this variable or specify a variable using idvar() that fully and uniquely identifies the data set.{p_end}"
					error 110

				}

				*Generate the ID var from row number
				gen `idvar' = _n

				*Store local indicating ID var generated has type numeric
				local IDtypeNumeric 1

			}
			else {

				*Make sure that user specified ID is uniquely and fully identifying the observations
				cap isid `idvar'
				if _rc != 0 {

					di as error "{pstd}Variable `idvar' specified in idvar() does not fully and uniquely identify the observations in the data set. Meaning that `idvar' is not allowed to have any duplicates or missing values. Make `idvar' uniquly and fully idnetifying or exclude the varaibleas using {inp:if} or {inp:in}.{p_end}"
					error 450

				}

				*Test if ID var is string or numeric
				cap confirm numeric variable `idvar'
				if _rc == 0 {

					*Store local indicating ID var type is numeric
					local IDtypeNumeric 1
				}
				else {

					*Store local indicating ID var type is numeric
					local IDtypeNumeric 0
				}
			}

			********************************
			*
			*	Checking and generating the MatchID and the MatchDiff var
			*
			********************************

			*Test input from user or test if deafault value is valiable
			iematchMatchVarCheck _matchID `matchidname'
			local matchIDname "`r(validVarName)'"

			*Allow the ID var used to be string
			if `IDtypeNumeric' == 1 {
				gen  `matchIDname' = .
			}
			else {
				gen  `matchIDname' = ""
			}

			*If many-to-one match used
			if "`m1'" != "" {
				iematchMatchVarCheck _matchCount `matchcountname'
				local matchCountName "`r(validVarName)'"
				gen `matchCountName' = .
			}
			else {

				*Option match count name is not allowed if it is a one-to-one match
				if "`matchcountname'" != "" {

					di as error "{pstd}Option {inp:matchcountname()} is only allowed in combination with option {inp:m1}.{p_end}"
					error 198
				}
			}

			iematchMatchVarCheck _matchDiff `matchdiffname'
			local matchDiffName "`r(validVarName)'"
			gen `matchDiffName' = .

			iematchMatchVarCheck _matchResult `matchresultname'
			local matchReasonName "`r(validVarName)'"
			gen `matchReasonName' = .

			*Create a label for missing values that explains no match
			label define matchLabel 0 "Not Matched" 1 "Matched" .i "Obs excluded due to if/in" .g "Missing value in `grpdummy'" .m "Missing value in `matchvar'" .d "No match within maxdiff"

			*Apply the label
			label value `matchReasonName' matchLabel

}

			********************************
			*
			*	Output exclude string
			*
			********************************

			if "`obsexcludstring'" != "" {

				noi di ""
				noi di "{hline}"
				noi di ""
				noi di "{pstd}{ul:Observations are excluded from the matching for the following reasons:}{break}"
				noi di "`obsexcludstring'{p_end}"

			}

		********************************
		*	Start matching
		********************************

			********************************
			*
			*	Creating tempvar used
			*
			********************************

			*Initiate the temporary variables used by this command
			tempvar prefID prefDiff matched

			gen `prefDiff' 		= .
			gen byte `matched' 	= 0

			*Allow the ID var used to be string
			if `IDtypeNumeric' == 1 {
				gen  `prefID' = .
			}
			else {
				gen  `prefID' = ""
			}

			** Generate the inverse of the matchvar to sort descending (gsort is too slow),
			*  a random var to seperate two values with the same match var, and the inverse
			*  of the random var for when sorting descending.
			tempvar rand invsort invrand

			sort `matchvar'
			gen  `invsort' = -1 * `matchvar'

			gen    `rand' = uniform()
			gen `invrand' = -1 * `rand'

			***********
			*Tempvars for matching

			*Diffvars, they are always numeric
			tempvar					 diffup   diffdo   valUp_0   valDo_0   valUp_1   valDo_1
			local 	 updownTempVars `diffup' `diffdo' `valUp_0' `valDo_0' `valUp_1' `valDo_1'

			foreach tempVar of local updownTempVars {

				gen `tempVar' = .
			}

			*ID vars, allowed to be both numeric and string
			tempvar					  	IDup   IDdo   IDup_0   IDdo_0   IDup_1   IDdo_1
			local 	 updownIDTempVars  `IDup' `IDdo' `IDup_0' `IDdo_0' `IDup_1' `IDdo_1'

			foreach tempVar of local updownIDTempVars {

				*Allow the ID var used to be string
				if `IDtypeNumeric' == 1 {
					gen  `tempVar' = .
				}
				else {
					gen  `tempVar' = ""
				}
			}

			***************************
			*
			*	One to one match
			*
			***************************

			if "`m1'" == "" {

				noi di ""
				noi di "{hline}{break}"
				noi di "{pstd}{ul:Matching one-to-one. Base observations left to match:}{p_end}"
				count if `grpdummy' == 1 & `matched' == 0
				local left2Match = `r(N)'
				noi di "{pstd}`left2Match' " _c

				*di "`idvar'"
				*di "`IDtypeNumeric'"
				*pause on
				*pause

				while (`left2Match' > 0) {

					*noi di 0

					**For all observations still to be matched, assign the preferred
					* match among the other unmatched observations
					qui updatePrefDiffPreffID `prefID' `prefDiff' `matchvar' `invsort' `idvar' `grpdummy' `matched' `rand' `invrand' `updownTempVars' `updownIDTempVars'

					*noi di 1

					if "`maxdiff'" != "" {

						replace `matched' 			= 1		if `prefDiff' > `maxdiff' & `grpdummy' == 1
						replace `matchReasonName' 	= .d 	if `prefDiff' > `maxdiff' & `grpdummy' == 1

						*Allow the ID var used to be string
						if `IDtypeNumeric' == 1 {
							replace `prefID'		= .		if `prefDiff' > `maxdiff'
						}
						else {
							replace `prefID'		= ""	if `prefDiff' > `maxdiff'
						}
					}

					*noi di 2

					replace `matched' = 1 if `matched' == 0 & `prefID' == `idvar'[_n-1] & `prefID'[_n-1] == `idvar'
					replace `matched' = 1 if `matched' == 0 & `prefID' == `idvar'[_n+1] & `prefID'[_n+1] == `idvar'

					*noi di 3

					count if `grpdummy' == 1 & `matched' == 0
					local left2Match = `r(N)'
					noi di "`left2Match' " _c

				}
				noi di "{p_end}" _c

			}

			***************************
			*
			*	Many to one match
			*
			***************************
			else {

				updatePrefDiffPreffID `prefID' `prefDiff' `matchvar' `invsort' `idvar' `grpdummy' `matched' `rand' `invrand' `updownTempVars' `updownIDTempVars'

				if "`maxdiff'" != "" {

					replace `matched' 			= 1		if `prefDiff' > `maxdiff' & `grpdummy' == 1
					replace `matchReasonName' 	= .d 	if `prefDiff' > `maxdiff' & `grpdummy' == 1

					*Allow the ID var used to be string
					if `IDtypeNumeric' == 1 {
						replace `prefID'		= .		if `prefDiff' > `maxdiff'
					}
					else {
						replace `prefID'		= ""	if `prefDiff' > `maxdiff'
					}

				}

				replace `prefID'			=  `idvar' if `grpdummy' == 0
				bys 	`prefID' 			:   replace `matchCountName' = _N - 1

				**Replace prefID to missing for target obs that had no base
				* obs matched to it. T
				if `IDtypeNumeric' == 1 {
					*Id var is numeric
					replace `prefID'		= .		if `matchCountName' == 0
				}
				else {
					*id var is string
					replace `prefID'		= ""	if `matchCountName' == 0
				}

				*Only target obs with base obs prefering it are matched
				replace	 `matched' 			= 1		if `matchCountName' != 0

				*Remove values for target obs that were not matched
				replace  `matchCountName'	= . 	if `matchCountName' == 0
			}

			*Return vars
			replace `matchDiffName' 	= `prefDiff'	if `matched' == 1
			replace `matchIDname' 		= `idvar' 		if `matched' == 1 & `grpdummy' == 0
			replace `matchIDname' 		= `prefID' 		if `matched' == 1 & `grpdummy' == 1

			*Target obs not used
			replace `matchReasonName' = 0 if `matched' == 0 & `grpdummy' == 0

			*only keep output vars
			keep `matchIDname' `matchDiffName' `idvar' `originalSort' `matchReasonName' `matchCountName'

			tempfile mergefile

			save `mergefile'

		restore

		tempvar mergevar ifinvar

		merge 1:1  `originalSort' using `mergefile', gen(`mergevar')

		replace `matchReasonName' = .m if missing(`matchvar')
		replace `matchReasonName' = .g if missing(`grpdummy')

		if "`if'`in'" != "" {

			gen `ifinvar' = 1 `if'`in'
			replace `matchReasonName' = .i if `ifinvar' != 1
		}

		replace `matchReasonName' = 1 if `matchReasonName' == .

		*comress the variables generated
		compress  `matchIDname' `matchDiffName' `matchReasonName' `matchCountName'

		noi outputTable `matchReasonName' `grpdummy'

		sort `originalSort'

	}

	end

*Testing input (functions)
 if 1 {
	*Cheack matchVar input
	cap program drop 	iematchMatchVarCheck
		program define 	iematchMatchVarCheck  , rclass

		args defaultName userName

		if "`defaultName'" == "_matchID" 		local optionName matchidname
		if "`defaultName'" == "_matchDiff" 		local optionName matchdiffname
		if "`defaultName'" == "_matchResult" 	local optionName matchresult
		if "`defaultName'" == "_matchCount" 	local optionName matchcount

		*All the default names
		local dfltNms _noMatchReason _matchDiff _matchResult _matchCount

		*The other two default names
		local othDfltNms : list dfltNms - defaultName

		*Creating two locals with the deafult name in each local
		local Oth1 : word 1 of `othDfltNms'
		local Oth2 : word 2 of `othDfltNms'
		local Oth3 : word 3 of `othDfltNms'

		*Testing that the option name is not the same as the other variable's default name.
		if ("`userName'" == "`Oth1'" | "`userName'" == "`Oth2'" | "`userName'" == "`Oth3'" | "`userName'" == "_ID")  {

			noi di as error "{phang}The new name specified in `optionName'(`userName') is not allowed to be _ID, `Oth1', `Oth2', or `Oth3'{p_end}"
			error 198
		}

		*Checking set-up for the ID var used for _matchID
		if "`userName'" == "" {

			*CSet the default name
			local validMatchVarname `defaultName'

			*Make sure that the default name _ID is not already used
			cap confirm variable `validMatchVarname'
			if _rc == 0 {

				noi di as error "A variable with name `validMatchVarname' is already defined. Either drop this variable or specify a new variable name using `optionName'()."
				error 110

			}

		}

		else {

			*CSet the default name
			local validMatchVarname `userName'

			*Make sure that the default name _ID is not already used
			cap confirm variable `validMatchVarname'
			if _rc == 0 {

				noi di as error "The variable name specified in `optionName'(`userName') is already defined in the data set. Either drop this variable or specify a another variable name using `optionName'()."
				error 110

			}

		}

		*Testing that the new name is valid by creating a variable that is dropped immedeatly afterwards
		cap gen `validMatchVarname' = .

		if _rc != 0 {

			noi di as error "The variable name specified in `optionName'(`userName') is not a valid variable name."
			error _rc

		}
		drop `validMatchVarname'

		return local validVarName 	"`validMatchVarname'"

	end
}

*Matching functions
if 1 {

	** This function is called to assign the preferred match for all unmatched
	*  observations to any other unmatched observation. Returns a variable pref that is the
	cap program drop 	updatePrefDiffPreffID
		program define 	updatePrefDiffPreffID

		args prefID prefDiff matchvar invsort idvar grpvar matched rand invrand diffup diffdo valUp_0 valDo_0 valUp_1 valDo_1 IDup IDdo IDup_0 IDdo_0 IDup_1 IDdo_1

		*****************
		*Update possible matches with higher rank value
		sort `matched' `matchvar' `rand'

		updateBestValID 0 `matchvar' `idvar' `grpvar' `matched' `valUp_0' `IDup_0'
		updateBestValID 1 `matchvar' `idvar' `grpvar' `matched' `valUp_1' `IDup_1'

		*****************
		*Update possible matches with lower rank value
		sort `matched' `invsort' `invrand'

		updateBestValID 0 `matchvar' `idvar' `grpvar' `matched' `valDo_0' `IDdo_0'
		updateBestValID 1 `matchvar' `idvar' `grpvar' `matched' `valDo_1' `IDdo_1'

		*****************
		*Create one varaible common for both groups with diff upwards
		replace `diffup' 	= abs(`matchvar' - `valUp_1') if `grpvar' == 1
		replace `diffup' 	= abs(`matchvar' - `valUp_0') if `grpvar' == 0

		*Create one varaible common for both groups with diff downwards
		replace `diffdo' 	= abs(`matchvar' - `valDo_1') if `grpvar' == 1
		replace `diffdo' 	= abs(`matchvar' - `valDo_0') if `grpvar' == 0

		*Create one varaible common for both groups with ID upwards
		replace `IDup' 		= `IDup_1' 	if `grpvar' == 1
		replace `IDup' 		= `IDup_0' 	if `grpvar' == 0

		*Create one varaible common for both groups with ID downwards
		replace `IDdo' 		= `IDdo_1' 	if `grpvar' == 1
		replace `IDdo' 		= `IDdo_0' 	if `grpvar' == 0

		replace `prefID' 	= `IDdo' 	if `matched' == 0 & `diffdo' <= `diffup'
		replace `prefID' 	= `IDup' 	if `matched' == 0 & `diffdo' >  `diffup'

		replace `prefDiff' 	= `diffdo' 	if `matched' == 0 & `diffdo' <= `diffup'
		replace `prefDiff' 	= `diffup' 	if `matched' == 0 & `diffdo' >  `diffup'

	end

	** This function goes through the observatioins from top to down and copying
	*  the match value of the closest observation of the other group above to
	*  (bestVal) and the ccoprresponding ID to (bestID) for obe group at the time.
	*  To go from bottuom to top sort with invsort and apply this command.
	cap program drop 	updateBestValID
		program define 	updateBestValID

		args grpvl matchval idvar grpvar matched bestVal bestID

		*Test if ID var is string or numeric
		local IDNumeric 0
		cap confirm numeric variable `idvar'
		if _rc == 0 local IDNumeric 1

		*Reset all values
		replace `bestVal' 	= .
		if `IDNumeric' == 1 replace `bestID' 	= .
		if `IDNumeric' == 0 replace `bestID' 	= ""

		*Set the match value and ID of observations that are in the other group
		replace `bestVal'   = `matchval' 		if `grpvar' != `grpvl' & `matched' == 0
		replace `bestID'  	= `idvar' 			if `grpvar' != `grpvl' & `matched' == 0

		*Fill in that value from the observation in the other group until getting to another observation of the other group
							replace `bestVal'   = `bestVal'[_n-1]	if `bestVal' == .  & `matched' == 0
		if `IDNumeric' == 1 replace `bestID'  	= `bestID'[_n-1] 	if `bestID'	 == .  & `matched' == 0
		if `IDNumeric' == 0 replace `bestID'  	= `bestID'[_n-1] 	if `bestID'	 == "" & `matched' == 0

	end

}

	** This function goes through the observatioins from top to down and copying
	*  the match value of the closest observation of the other group above to
	*  (bestVal) and the ccoprresponding ID to (bestID) for obe group at the time.
	*  To go from bottuom to top sort with invsort and apply this command.
	cap program drop 	outputTable
		program define 	outputTable

		qui {
			args resultVar grpdum

			local maxResultLen 16

			local allResults 1 0 .d .i .g .m

			levelsof `resultVar' , missing local(resultsUsed)

			foreach result of local resultsUsed {

				if `result' == 1  local thisLen 7
				if `result' == 0  local thisLen 11
				if `result' == .d local thisLen 25
				if `result' == .i local thisLen 18
				if `result' == .g local thisLen 18
				if `result' == .m local thisLen 18

				local maxResultLen = max(`maxResultLen' , `thisLen')
			}

			local missingGrpDum 0
			count if missing(`grpdum')
			if `r(N)' > 0 local missingGrpDum 1

			local R1 "{col 4}{c |}"

			local col1width = `maxResultLen' + 3 //28
			local hli1 "{hline `col1width'}"
			local cen1 "{center `col1width':"

			local col2border = `maxResultLen' + 8 //33
			local R2  "{col `col2border'}{c |}"
			local R2a "{col `col2border'}"

			local col3border = `maxResultLen' + 19 //44
			local R3 "{col `col3border'}{c |}"

			local col4border = `maxResultLen' + 32 //57
			local R4 "{col `col4border'}{c |}"

			local grpdumCentre 23

			local lastT  	"{c RT}"
			local lastTdown	"{c RT}"
			local lastC  	"{c BRC}"

			if `missingGrpDum' {

				local lastT 		"{c +}{hline 9}{c RT}"
				local lastTdown 	"{c BT}{hline 9}{c RT}"
				local lastC 		"{c BT}{hline 9}{c BRC}"
				local missTitle 	"  missing "
				local grpdumCentre 	33

			}

			noi di ""
			noi di ""
			noi di "{hline}"
			noi di ""
			noi di "{pstd}{ul:Output of Matching Result:}{p_end}"
			noi di ""
			noi di "{col 5}`cen1'`resultVar'}`R2a' {centre `grpdumCentre':tmt }"
			noi di "{col 4}{c LT}`hli1'{c +}{hline `grpdumCentre'}{c RT}"
			noi di "`R1'`cen1'value and result}`R2' 1 (base)   0 (target) `missTitle'{c |}"
			noi di "{col 4}{c LT}`hli1'{c +}{hline 10}{c +}{hline 12}`lastT'"

			foreach result of local allResults {

				if `:list result in resultsUsed' {

					qui count if `resultVar' == `result' & `grpdum' == 1
					local numBase = trim("`: display %16.0gc  `r(N)''")

					qui count if `resultVar' == `result' & `grpdum' == 0
					local numTarg = trim("`: display %16.0gc  `r(N)''")

					if `missingGrpDum' {

						qui count if `resultVar' == `result' & missing(`grpdum')
						local numMiss = trim("`: display %16.0gc  `r(N)''")

						local missCol "{ralign 9 :`numMiss' }{c |}"

					}

					local numCols "`R2'{ralign 10 :`numBase' }`R3'{ralign 12 :`numTarg' }`R4'`missCol'"

					if `result' == 1  noi di "`R1' 1 Matched`numCols'"
					if `result' == 0  noi di "`R1' 0 Not matched`numCols'"
					if `result' == .d noi di "`R1'.d No match within maxdiff()`numCols'"
					if `result' == .i noi di "`R1'.i Excl. using if/in`numCols'"
					if `result' == .g noi di "`R1'.g Missing grpdummy()`numCols'"
					if `result' == .m noi di "`R1'.m Missing matchvar()`numCols'"
				}
			}
			noi di "{col 4}{c LT}`hli1'{c +}{hline 10}{c +}{hline 12}`lastT'"

			qui count if `grpdum' == 1
			local numBase = trim("`: display %16.0gc  `r(N)''")

			qui count if `grpdum' == 0
			local numTarg = trim("`: display %16.0gc  `r(N)''")

			if `missingGrpDum' {

				qui count if missing(`grpdum')
				local numMiss = trim("`: display %16.0gc  `r(N)''")

				local missCol "{ralign 9 :`numMiss' }{c |}"

			}

			noi di "`R1'`cen1'N per group}`R2'{ralign 10 :`numBase' }`R3'{ralign 12 :`numTarg' }`R4'`missCol'"
			noi di "{col 4}{c LT}`hli1'{c +}{hline 10}{c BT}{hline 12}`lastTdown'"

			qui count
			local numTot = trim("`: display %16.0gc  `r(N)''")

			noi di "`R1'`cen1'Total N}`R2'{centre `grpdumCentre':`numTot'}`R4'"
			noi di "{col 4}{c BLC}`hli1'{c BT}{hline `grpdumCentre'}{c BRC}"
		}
	end

	cap program drop 	iematch
	    program define	iematch

		noi di "Command OK!"

		syntax  [if] [in]  , 					///
			GRPdummy(varname) 					///
			MATCHvar(varname) 					///
			[									///
			IDvar(varname)						///
			m1									///
			maxdiff(numlist max = 1 min = 1) 	///
			seedok						 		///
			MATCHIDname(string)					///
			MATCHDIffname(string)				///
			MATCHREsultname(string)				///
			MATCHCOuntname(string)				///
			]

		*****
		*1 format errors as smcl
		*2 option to disable countdown
		*5 a table with results outputted

		noi di "Syntax OK!"

		pause on

		qui {

		********************************
		*
		*	Gen temp sort and merge var
		*
		********************************

		tempvar originalSort ifinvar

		gen `originalSort' = _n

		preserve

*Testing input
if 1 {

			local obsexcludstring ""

			*Deal with if and in and display info.
			if "`if'`in'" != "" {

				gen `ifinvar' = 1 `if'`in'

				count if `ifinvar' != 1
				if `r(N)' > 0 {

					*This is not an error just outputting the number
					local obsexcludstring "`obsexcludstring'`r(N)' observation(s) were excluded in {inp:if}/{inp:in}: (`if'`in').{break}"

				}

				keep `if'`in'
			}

			********************************
			*
			*	Checking group dummy
			*
			********************************

			*Test that the group dummy is 1, 0 or missing
			cap assert inlist(`grpdummy', 1, 0, .) | `grpdummy' > .
			if _rc != 0 {

				di as error "{pstd}The variable in grpdummy(`grpdummy') is not a dummy variable. The variable is only allowed to have the values 1, 0 or missing. Observations with missing varaibles in the grpdummy are ignored by this command.{p_end}"
				error _rc
			}

			**Exclude obs with missing value in groupdummy

			*Count number of obs to be dropped and and output that number if more than zero
			count if missing(`grpdummy')
			if `r(N)' > 0 {

				*This is not an error just outputting the number
				local obsexcludstring  "`obsexcludstring'`r(N)' observation(s) were excluded due to missing value in  grpdummy(`grpdummy').{break}"
			}
			*Drop obs with missing
			drop if missing(`grpdummy')

			********************************
			*
			*	Checking match continous var
			*
			********************************

			*Test that the continous is numeric
			cap confirm numeric variable `matchvar'
			if _rc != 0 {

				noi di as error "{pstd}The variable to match on specified in matchvar(`matchvar') is not a numeric variable.{p_end}"
				error 109

			}

			**All variables with value 1 or 0 in the group dummy and
			* not excluded by if/in must have a value in matchvar
			count if missing(`matchvar')
			if `r(N)' > 0 {
				local obsexcludstring  "`obsexcludstring'`r(N)' observation(s) were excluded due to missing value in matchvar(`matchvar').{break}"

			}
			*Drop obs with missing
			drop if missing(`matchvar')

			********************************
			*
			*	Checking match var and group dummy are unique
			*
			********************************

			if "`seedok'" == "" {

				**test that there are no duplicates in match
				* var within each type of observation
				cap isid `matchvar' `grpdummy'

				if _rc != 0 {

					noi di as error "{pstd}There are base observations or target observations {...}"
					noi di as error "with duplicate values in matchvar(`matchvar'). To guarantee {...}"
					noi di as error "a replicable match you must {help seed:set a seed}. To supress {...}"
					noi di as error "this error message after you have set a the seed, or if a {...}"
					noi di as error "replicable match is not important to you, use option {inp:seedok}{p_end}"
					error 198

				}
			}

			********************************
			*
			*	Checking that there are more target
			*	obs than base obs in a 1-to-1 match
			*
			********************************

			if "`m1'" == "" {

				*Count number of base vars
				count if `grpdummy' == 1
				local numBaseObs `r(N)'

				*Count number of target vars
				count if `grpdummy' == 0
				local numTrgtObs `r(N)'

				*Test that there are more target
				cap assert `numTrgtObs' >= `numBaseObs'

				if _rc != 0 {

					noi di as error "{pstd}There are more base observations than target observations. This is not allowed in a one-to-one match. See option {inp:m1} for an alternaitve matching where it is allowed to have more base observations than target ovbservations.{p_end}"
					error _rc
				}
			}

			********************************
			*
			*	Checking duplicates in variable names in options
			*
			********************************

			*Create a local of all varnames used in any option
			local allnewvars `idvar' `matchidname' `matchdiffname' `matchresult'

			*Check if there are any duplicates in the local of all varnames in options
			local dupnewvars : list dups allnewvars

			*Throw error if there were any duplicates
			if "`dupnewvars'" != "" {

				di as error "{pstd}The same new variable name was used twice or more in the options generating a new variable. Go back and check syntax.{p_end}"
				error 198

			}

			********************************
			*
			*	Checking ID var
			*
			********************************

			*Checking set-up for the ID var used for _matchID
			if "`idvar'" == "" {

				*Copy this name
				local idvar _ID

				*Make sure that the default name _ID is not already used
				cap confirm variable `idvar'
				if _rc == 0 {

					di as error "{pstd}A variable with name `idvar' is already defined. Either drop this variable or specify a variable using idvar() that fully and uniquely identifies the data set.{p_end}"
					error 110

				}

				*Generate the ID var from row number
				gen `idvar' = _n

				*Store local indicating ID var generated has type numeric
				local IDtypeNumeric 1

			}
			else {

				*Make sure that user specified ID is uniquely and fully identifying the observations
				cap isid `idvar'
				if _rc != 0 {

					di as error "{pstd}Variable `idvar' specified in idvar() does not fully and uniquely identify the observations in the data set. Meaning that `idvar' is not allowed to have any duplicates or missing values. Make `idvar' uniquly and fully idnetifying or exclude the varaibleas using {inp:if} or {inp:in}.{p_end}"
					error 450

				}

				*Test if ID var is string or numeric
				cap confirm numeric variable `idvar'
				if _rc == 0 {

					*Store local indicating ID var type is numeric
					local IDtypeNumeric 1
				}
				else {

					*Store local indicating ID var type is numeric
					local IDtypeNumeric 0
				}
			}

			********************************
			*
			*	Checking and generating the MatchID and the MatchDiff var
			*
			********************************

			*Test input from user or test if deafault value is valiable
			iematchMatchVarCheck _matchID `matchidname'
			local matchIDname "`r(validVarName)'"

			*Allow the ID var used to be string
			if `IDtypeNumeric' == 1 {
				gen  `matchIDname' = .
			}
			else {
				gen  `matchIDname' = ""
			}

			*If many-to-one match used
			if "`m1'" != "" {
				iematchMatchVarCheck _matchCount `matchcountname'
				local matchCountName "`r(validVarName)'"
				gen `matchCountName' = .
			}
			else {

				*Option match count name is not allowed if it is a one-to-one match
				if "`matchcountname'" != "" {

					di as error "{pstd}Option {inp:matchcountname()} is only allowed in combination with option {inp:m1}.{p_end}"
					error 198
				}
			}

			iematchMatchVarCheck _matchDiff `matchdiffname'
			local matchDiffName "`r(validVarName)'"
			gen `matchDiffName' = .

			iematchMatchVarCheck _matchResult `matchresultname'
			local matchReasonName "`r(validVarName)'"
			gen `matchReasonName' = .

			*Create a label for missing values that explains no match
			label define matchLabel 0 "Not Matched" 1 "Matched" .i "Obs excluded due to if/in" .g "Missing value in `grpdummy'" .m "Missing value in `matchvar'" .d "No match within maxdiff"

			*Apply the label
			label value `matchReasonName' matchLabel

}

			********************************
			*
			*	Output exclude string
			*
			********************************

			if "`obsexcludstring'" != "" {

				noi di ""
				noi di "{hline}"
				noi di ""
				noi di "{pstd}{ul:Observations are excluded from the matching for the following reasons:}{break}"
				noi di "`obsexcludstring'{p_end}"

			}

		********************************
		*	Start matching
		********************************

			********************************
			*
			*	Creating tempvar used
			*
			********************************

			*Initiate the temporary variables used by this command
			tempvar prefID prefDiff matched

			gen `prefDiff' 		= .
			gen byte `matched' 	= 0

			*Allow the ID var used to be string
			if `IDtypeNumeric' == 1 {
				gen  `prefID' = .
			}
			else {
				gen  `prefID' = ""
			}

			** Generate the inverse of the matchvar to sort descending (gsort is too slow),
			*  a random var to seperate two values with the same match var, and the inverse
			*  of the random var for when sorting descending.
			tempvar rand invsort invrand

			sort `matchvar'
			gen  `invsort' = -1 * `matchvar'

			gen    `rand' = uniform()
			gen `invrand' = -1 * `rand'

			***********
			*Tempvars for matching

			*Diffvars, they are always numeric
			tempvar					 diffup   diffdo   valUp_0   valDo_0   valUp_1   valDo_1
			local 	 updownTempVars `diffup' `diffdo' `valUp_0' `valDo_0' `valUp_1' `valDo_1'

			foreach tempVar of local updownTempVars {

				gen `tempVar' = .
			}

			*ID vars, allowed to be both numeric and string
			tempvar					  	IDup   IDdo   IDup_0   IDdo_0   IDup_1   IDdo_1
			local 	 updownIDTempVars  `IDup' `IDdo' `IDup_0' `IDdo_0' `IDup_1' `IDdo_1'

			foreach tempVar of local updownIDTempVars {

				*Allow the ID var used to be string
				if `IDtypeNumeric' == 1 {
					gen  `tempVar' = .
				}
				else {
					gen  `tempVar' = ""
				}
			}

			***************************
			*
			*	One to one match
			*
			***************************

			if "`m1'" == "" {

				noi di ""
				noi di "{hline}{break}"
				noi di "{pstd}{ul:Matching one-to-one. Base observations left to match:}{p_end}"
				count if `grpdummy' == 1 & `matched' == 0
				local left2Match = `r(N)'
				noi di "{pstd}`left2Match' " _c

				*di "`idvar'"
				*di "`IDtypeNumeric'"
				*pause on
				*pause

				while (`left2Match' > 0) {

					*noi di 0

					**For all observations still to be matched, assign the preferred
					* match among the other unmatched observations
					qui updatePrefDiffPreffID `prefID' `prefDiff' `matchvar' `invsort' `idvar' `grpdummy' `matched' `rand' `invrand' `updownTempVars' `updownIDTempVars'

					*noi di 1

					if "`maxdiff'" != "" {

						replace `matched' 			= 1		if `prefDiff' > `maxdiff' & `grpdummy' == 1
						replace `matchReasonName' 	= .d 	if `prefDiff' > `maxdiff' & `grpdummy' == 1

						*Allow the ID var used to be string
						if `IDtypeNumeric' == 1 {
							replace `prefID'		= .		if `prefDiff' > `maxdiff'
						}
						else {
							replace `prefID'		= ""	if `prefDiff' > `maxdiff'
						}
					}

					*noi di 2

					replace `matched' = 1 if `matched' == 0 & `prefID' == `idvar'[_n-1] & `prefID'[_n-1] == `idvar'
					replace `matched' = 1 if `matched' == 0 & `prefID' == `idvar'[_n+1] & `prefID'[_n+1] == `idvar'

					*noi di 3

					count if `grpdummy' == 1 & `matched' == 0
					local left2Match = `r(N)'
					noi di "`left2Match' " _c

				}
				noi di "{p_end}" _c

			}

			***************************
			*
			*	Many to one match
			*
			***************************
			else {

				updatePrefDiffPreffID `prefID' `prefDiff' `matchvar' `invsort' `idvar' `grpdummy' `matched' `rand' `invrand' `updownTempVars' `updownIDTempVars'

				if "`maxdiff'" != "" {

					replace `matched' 			= 1		if `prefDiff' > `maxdiff' & `grpdummy' == 1
					replace `matchReasonName' 	= .d 	if `prefDiff' > `maxdiff' & `grpdummy' == 1

					*Allow the ID var used to be string
					if `IDtypeNumeric' == 1 {
						replace `prefID'		= .		if `prefDiff' > `maxdiff'
					}
					else {
						replace `prefID'		= ""	if `prefDiff' > `maxdiff'
					}

				}

				replace `prefID'			=  `idvar' if `grpdummy' == 0
				bys 	`prefID' 			:   replace `matchCountName' = _N - 1

				**Replace prefID to missing for target obs that had no base
				* obs matched to it. T
				if `IDtypeNumeric' == 1 {
					*Id var is numeric
					replace `prefID'		= .		if `matchCountName' == 0
				}
				else {
					*id var is string
					replace `prefID'		= ""	if `matchCountName' == 0
				}

				*Only target obs with base obs prefering it are matched
				replace	 `matched' 			= 1		if `matchCountName' != 0

				*Remove values for target obs that were not matched
				replace  `matchCountName'	= . 	if `matchCountName' == 0
			}

			*Return vars
			replace `matchDiffName' 	= `prefDiff'	if `matched' == 1
			replace `matchIDname' 		= `idvar' 		if `matched' == 1 & `grpdummy' == 0
			replace `matchIDname' 		= `prefID' 		if `matched' == 1 & `grpdummy' == 1

			*Target obs not used
			replace `matchReasonName' = 0 if `matched' == 0 & `grpdummy' == 0

			*only keep output vars
			keep `matchIDname' `matchDiffName' `idvar' `originalSort' `matchReasonName' `matchCountName'

			tempfile mergefile

			save `mergefile'

		restore

		tempvar mergevar ifinvar

		merge 1:1  `originalSort' using `mergefile', gen(`mergevar')

		replace `matchReasonName' = .m if missing(`matchvar')
		replace `matchReasonName' = .g if missing(`grpdummy')

		if "`if'`in'" != "" {

			gen `ifinvar' = 1 `if'`in'
			replace `matchReasonName' = .i if `ifinvar' != 1
		}

		replace `matchReasonName' = 1 if `matchReasonName' == .

		*comress the variables generated
		compress  `matchIDname' `matchDiffName' `matchReasonName' `matchCountName'

		noi outputTable `matchReasonName' `grpdummy'

		sort `originalSort'

	}

	end

*Testing input (functions)
 if 1 {
	*Cheack matchVar input
	cap program drop 	iematchMatchVarCheck
		program define 	iematchMatchVarCheck  , rclass

		args defaultName userName

		if "`defaultName'" == "_matchID" 		local optionName matchidname
		if "`defaultName'" == "_matchDiff" 		local optionName matchdiffname
		if "`defaultName'" == "_matchResult" 	local optionName matchresult
		if "`defaultName'" == "_matchCount" 	local optionName matchcount

		*All the default names
		local dfltNms _noMatchReason _matchDiff _matchResult _matchCount

		*The other two default names
		local othDfltNms : list dfltNms - defaultName

		*Creating two locals with the deafult name in each local
		local Oth1 : word 1 of `othDfltNms'
		local Oth2 : word 2 of `othDfltNms'
		local Oth3 : word 3 of `othDfltNms'

		*Testing that the option name is not the same as the other variable's default name.
		if ("`userName'" == "`Oth1'" | "`userName'" == "`Oth2'" | "`userName'" == "`Oth3'" | "`userName'" == "_ID")  {

			noi di as error "{phang}The new name specified in `optionName'(`userName') is not allowed to be _ID, `Oth1', `Oth2', or `Oth3'{p_end}"
			error 198
		}

		*Checking set-up for the ID var used for _matchID
		if "`userName'" == "" {

			*CSet the default name
			local validMatchVarname `defaultName'

			*Make sure that the default name _ID is not already used
			cap confirm variable `validMatchVarname'
			if _rc == 0 {

				noi di as error "A variable with name `validMatchVarname' is already defined. Either drop this variable or specify a new variable name using `optionName'()."
				error 110

			}

		}

		else {

			*CSet the default name
			local validMatchVarname `userName'

			*Make sure that the default name _ID is not already used
			cap confirm variable `validMatchVarname'
			if _rc == 0 {

				noi di as error "The variable name specified in `optionName'(`userName') is already defined in the data set. Either drop this variable or specify a another variable name using `optionName'()."
				error 110

			}

		}

		*Testing that the new name is valid by creating a variable that is dropped immedeatly afterwards
		cap gen `validMatchVarname' = .

		if _rc != 0 {

			noi di as error "The variable name specified in `optionName'(`userName') is not a valid variable name."
			error _rc

		}
		drop `validMatchVarname'

		return local validVarName 	"`validMatchVarname'"

	end
}

*Matching functions
if 1 {

	** This function is called to assign the preferred match for all unmatched
	*  observations to any other unmatched observation. Returns a variable pref that is the
	cap program drop 	updatePrefDiffPreffID
		program define 	updatePrefDiffPreffID

		args prefID prefDiff matchvar invsort idvar grpvar matched rand invrand diffup diffdo valUp_0 valDo_0 valUp_1 valDo_1 IDup IDdo IDup_0 IDdo_0 IDup_1 IDdo_1

		*****************
		*Update possible matches with higher rank value
		sort `matched' `matchvar' `rand'

		updateBestValID 0 `matchvar' `idvar' `grpvar' `matched' `valUp_0' `IDup_0'
		updateBestValID 1 `matchvar' `idvar' `grpvar' `matched' `valUp_1' `IDup_1'

		*****************
		*Update possible matches with lower rank value
		sort `matched' `invsort' `invrand'

		updateBestValID 0 `matchvar' `idvar' `grpvar' `matched' `valDo_0' `IDdo_0'
		updateBestValID 1 `matchvar' `idvar' `grpvar' `matched' `valDo_1' `IDdo_1'

		*****************
		*Create one varaible common for both groups with diff upwards
		replace `diffup' 	= abs(`matchvar' - `valUp_1') if `grpvar' == 1
		replace `diffup' 	= abs(`matchvar' - `valUp_0') if `grpvar' == 0

		*Create one varaible common for both groups with diff downwards
		replace `diffdo' 	= abs(`matchvar' - `valDo_1') if `grpvar' == 1
		replace `diffdo' 	= abs(`matchvar' - `valDo_0') if `grpvar' == 0

		*Create one varaible common for both groups with ID upwards
		replace `IDup' 		= `IDup_1' 	if `grpvar' == 1
		replace `IDup' 		= `IDup_0' 	if `grpvar' == 0

		*Create one varaible common for both groups with ID downwards
		replace `IDdo' 		= `IDdo_1' 	if `grpvar' == 1
		replace `IDdo' 		= `IDdo_0' 	if `grpvar' == 0

		replace `prefID' 	= `IDdo' 	if `matched' == 0 & `diffdo' <= `diffup'
		replace `prefID' 	= `IDup' 	if `matched' == 0 & `diffdo' >  `diffup'

		replace `prefDiff' 	= `diffdo' 	if `matched' == 0 & `diffdo' <= `diffup'
		replace `prefDiff' 	= `diffup' 	if `matched' == 0 & `diffdo' >  `diffup'

	end

	** This function goes through the observatioins from top to down and copying
	*  the match value of the closest observation of the other group above to
	*  (bestVal) and the ccoprresponding ID to (bestID) for obe group at the time.
	*  To go from bottuom to top sort with invsort and apply this command.
	cap program drop 	updateBestValID
		program define 	updateBestValID

		args grpvl matchval idvar grpvar matched bestVal bestID

		*Test if ID var is string or numeric
		local IDNumeric 0
		cap confirm numeric variable `idvar'
		if _rc == 0 local IDNumeric 1

		*Reset all values
		replace `bestVal' 	= .
		if `IDNumeric' == 1 replace `bestID' 	= .
		if `IDNumeric' == 0 replace `bestID' 	= ""

		*Set the match value and ID of observations that are in the other group
		replace `bestVal'   = `matchval' 		if `grpvar' != `grpvl' & `matched' == 0
		replace `bestID'  	= `idvar' 			if `grpvar' != `grpvl' & `matched' == 0

		*Fill in that value from the observation in the other group until getting to another observation of the other group
							replace `bestVal'   = `bestVal'[_n-1]	if `bestVal' == .  & `matched' == 0
		if `IDNumeric' == 1 replace `bestID'  	= `bestID'[_n-1] 	if `bestID'	 == .  & `matched' == 0
		if `IDNumeric' == 0 replace `bestID'  	= `bestID'[_n-1] 	if `bestID'	 == "" & `matched' == 0

	end

}

	** This function goes through the observatioins from top to down and copying
	*  the match value of the closest observation of the other group above to
	*  (bestVal) and the ccoprresponding ID to (bestID) for obe group at the time.
	*  To go from bottuom to top sort with invsort and apply this command.
	cap program drop 	outputTable
		program define 	outputTable

		qui {
			args resultVar grpdum

			local maxResultLen 16

			local allResults 1 0 .d .i .g .m

			levelsof `resultVar' , missing local(resultsUsed)

			foreach result of local resultsUsed {

				if `result' == 1  local thisLen 7
				if `result' == 0  local thisLen 11
				if `result' == .d local thisLen 25
				if `result' == .i local thisLen 18
				if `result' == .g local thisLen 18
				if `result' == .m local thisLen 18

				local maxResultLen = max(`maxResultLen' , `thisLen')
			}

			local missingGrpDum 0
			count if missing(`grpdum')
			if `r(N)' > 0 local missingGrpDum 1

			local R1 "{col 4}{c |}"

			local col1width = `maxResultLen' + 3 //28
			local hli1 "{hline `col1width'}"
			local cen1 "{center `col1width':"

			local col2border = `maxResultLen' + 8 //33
			local R2  "{col `col2border'}{c |}"
			local R2a "{col `col2border'}"

			local col3border = `maxResultLen' + 19 //44
			local R3 "{col `col3border'}{c |}"

			local col4border = `maxResultLen' + 32 //57
			local R4 "{col `col4border'}{c |}"

			local grpdumCentre 23

			local lastT  	"{c RT}"
			local lastTdown	"{c RT}"
			local lastC  	"{c BRC}"

			if `missingGrpDum' {

				local lastT 		"{c +}{hline 9}{c RT}"
				local lastTdown 	"{c BT}{hline 9}{c RT}"
				local lastC 		"{c BT}{hline 9}{c BRC}"
				local missTitle 	"  missing "
				local grpdumCentre 	33

			}

			noi di ""
			noi di ""
			noi di "{hline}"
			noi di ""
			noi di "{pstd}{ul:Output of Matching Result:}{p_end}"
			noi di ""
			noi di "{col 5}`cen1'`resultVar'}`R2a' {centre `grpdumCentre':tmt }"
			noi di "{col 4}{c LT}`hli1'{c +}{hline `grpdumCentre'}{c RT}"
			noi di "`R1'`cen1'value and result}`R2' 1 (base)   0 (target) `missTitle'{c |}"
			noi di "{col 4}{c LT}`hli1'{c +}{hline 10}{c +}{hline 12}`lastT'"

			foreach result of local allResults {

				if `:list result in resultsUsed' {

					qui count if `resultVar' == `result' & `grpdum' == 1
					local numBase : display %9.0gc `r(N)'

					qui count if `resultVar' == `result' & `grpdum' == 0
					local numTarg : display %9.0gc `r(N)'

					if `missingGrpDum' {

						qui count if `resultVar' == `result' & missing(`grpdum')
						local numMiss `r(N)'

						local missCol "{ralign 9 :`numMiss' }{c |}"

					}

					local numCols "`R2'{ralign 10 :`numBase' }`R3'{ralign 12 :`numTarg' }`R4'`missCol'"

					if `result' == 1  noi di "`R1' 1 Matched`numCols'"
					if `result' == 0  noi di "`R1' 0 Not matched`numCols'"
					if `result' == .d noi di "`R1'.d No match within maxdiff()`numCols'"
					if `result' == .i noi di "`R1'.i Excl. using if/in`numCols'"
					if `result' == .g noi di "`R1'.g Missing grpdummy()`numCols'"
					if `result' == .m noi di "`R1'.m Missing matchvar()`numCols'"
				}
			}
			noi di "{col 4}{c LT}`hli1'{c +}{hline 10}{c +}{hline 12}`lastT'"

			qui count if `grpdum' == 1
			local numBase : display %9.0gc `r(N)'

			qui count if `grpdum' == 0
			local numTarg : display %9.0gc `r(N)'

			if `missingGrpDum' {

				qui count if missing(`grpdum')
				local numMiss : display %9.0gc `r(N)'

				local missCol "{ralign 9 :`numMiss' }{c |}"

			}

			noi di "`R1'`cen1'N per group}`R2'{ralign 10 :`numBase' }`R3'{ralign 12 :`numTarg' }`R4'`missCol'"
			noi di "{col 4}{c LT}`hli1'{c +}{hline 10}{c BT}{hline 12}`lastTdown'"

			qui count
			local numTot : display %9.0gc `r(N)'

			noi di "`R1'`cen1'Total N}`R2'{centre `grpdumCentre':`numTot'}`R4'"
			noi di "{col 4}{c BLC}`hli1'{c BT}{hline `grpdumCentre'}{c BRC}"
		}
	end


missing value edits for bettertab

missing value edits for bettertab

*! V0.1 31012017, Apoorva Lal
// wrapper for tab / tab2 that adds value prefixes for factor variables
cap pr drop bettertab
pr def bettertab
	version 6
	syntax varlist [if] [in] [, NMissing]
	marksample touse, novarlist
	loc nvars : list sizeof varlist
	if `nvars' == 1 {
		loc tabcmd tab
	}
	else {
		loc tabcmd tab2
	}
	if "`nmissing'" != "" {
		loc opt " "
	}
	else {
		loc opt ", m"
	}

	loc label_list ""
	foreach v in `varlist' {
		cap conf var `v'
		if !_rc {
			loc la_`v': value label `v'
		}
		else {
			noi di "`v' not found"
			error
		}
	}
	cap numlabel `label_list', add
	`tabcmd' `varlist' if `touse'`opt'
	cap numlabel `label_list', remove
end

*! V0.1 31012017, Apoorva Lal
// wrapper for tab / tab2 that adds value prefixes for factor variables
cap pr drop bettertab
pr def bettertab
	version 6
	syntax varlist [if] [in]
	marksample touse
	loc nvars : list sizeof varlist
	if `nvars' == 1 {
		loc tabcmd tab
	}
	else {
		loc tabcmd tab2
	}
	loc label_list ""
	foreach v in `varlist' {
		cap conf var `v'
		if !_rc {
			loc la_`v': value label `v'
			loc label_list `label_list' `la_`v''
		}
		else {
			noi di "`v' not found"
			error
		}
	}
	numlabel `label_list', add
	`tabcmd' `varlist' if `touse'
	numlabel `label_list', remove
end