Template Files

The asdocx’s templates / add-ins are program files that are written with the ado extension, just like any other Stata program. These templates can be extremely useful in creating a custom output table, especially when the table is a standard requirement in your field of research. In this tutorial, I am going to develop a template for reporting regression results in a format that is frequently used in the epidemiology research. Following is the complete code of the template, which I shall explain in details.

*! Custom Regression table for Epidemiologists
*! Version 1.3: March 14, 2021: by Attaullah Shah

1 program define asdocx_reg1
3	//gettoken command 0 : 0
4	syntax anything [if] [in], [title(str) notes(str) modifytype(str) ///
5		dect(str) dec(str) btp *]
8	if "$modifytype" == "replace" {
9	    cap rm $active_flexmat_file
10		loc location 1
11	}
12	else {
13		flexmat showmat ,  filename($active_flexmat_file) qui getlocinfo
14		if "$flexmat_current_loc" == "" {
15			loc location 1
16		}
17		else loc location = $flexmat_current_loc + 1
18	}
20	flexmat addrow, data(Variable, OR [95% CI], P-value) ///
21      row(`ThisRow') filename($active_flexmat_file) location(`location') qui 
22	loc ThisRow = 2
23	`anything' `if' `in', `options'
25	//loc dec 2
26	loc depvar `e(depvar)'
27	loc N `e(N)'
28	matrix table = r(table)
29	local varnames : colfullnames table
30	loc nvars : word count `varnames'
32	loc c = 1
34	foreach v of local varnames {
36		loc hzratio : dis %9.`dec'f = table[1, `c']
37		loc ll : dis %9.`dec'f = table[5,`c']
38		loc ul : dis %9.`dec'f = table[6,`c']
39		loc pvalue : dis %9.`dec'f = table[4,`c']
41		loc hzratio `hzratio' [`ll'\comma `ul']
43		forv i = 1 / 6 {
44			loc hzratio = subinstr("`hzratio'", "[ ", "[", .)
45		}
47		if "`btp'" != "" {
48		    loc hzratio = subinstr("`hzratio'", "[", "\openpar", .)
49			loc hzratio = subinstr("`hzratio'", "]", "\closepar", .)
51		}
53		loc v = subinstr("`v'", "`e(depvar)':", "", .)
55		if strmatch("`v'", "*b.*") {
56			loc hzratio
57			loc pvalue
58		}
59		mata: st_local("varLabel", getlable("`v'"))
60		loc varLabel = subinstr("`varLabel'", ",", "\comma", .)
61		loc varLabel = subinstr("`varLabel'", "_cons", "Constant", .)
62		if ("`varLabel'" == "Constant" & "${drop}" == "constant") continue 
64		else {						
65			flexmat addrow, data("`varLabel'", `hzratio', `pvalue' ) qui ///
66				row(`ThisRow') filename($active_flexmat_file) ///
67                              location(`location') 
69			loc `++ThisRow'
70			loc `++c'
72		}
73	}
74	flexmat addrow, data(Observations, , `N' ) qui ///
75	        row(`ThisRow') filename($active_flexmat_file) location(`location') 
77	if "`title'" == "" loc title Table: Regression Results - `depvar'
78	if "`notes'" == "" loc notes "Notes:"
80	mata {
81		flexmat_fmtmat = J(2,2,"")
82		flexmat_fmtmat[1,1] = "title"
83		flexmat_fmtmat[1,2] = "`title'"
84		flexmat_fmtmat[2,1] = "notes"
85		flexmat_fmtmat[2,2] = "`notes'"	
86	}
87	flexmat fmtmat, file("$active_flexmat_file") loc(`location')  hide	
89	glob drop
90 end


A Short note on the flexmat program

The template file uses the flexmat program, that is part of the asdocx package. If you have not already studied flexmat program, believe me it is a good investment of time to study it [Quick Start can be found here]. flexmat is a powerful tool that creates Tables in the Mata language. It is extremely flexible in a sense that you can add cells, columns, and rows to an existing or new tables at any location of the table. It hardly throws any error of matrix compatibility. Once it creates a table, then asdocx converts that table to Word, Excel or LaTeX format.

The use of global macros in the template file

The template files uses two global macro. These are discussed below.

$active_flexmat_file  : This macro contains the flexmat file name that is currently in use. When asdocx creates a matrix of output in the Mata format, then flexmat stores that output to a file, which is then further processed in by the asdocx’s output routines (i.e. Word, Excel, LaTeX). In the template file, we get the file name through this macro and write output from the template file to this file name.

$flexmat_current_loc : This macro contains the location information where the current output will be stored. If you have already read the flexmat documentation, you shall recall that flexmat stores the output matrices, table titles, and notes in locations that are numbered. Actually, we do not have to worry about the location numbers, as flexmat takes care of these on its own. We just have to supply the location number using this macro.

A walk through the template file

Line 1:  program define asdocx_reg1 : The template file starts with program definition statement. All template files must start with the prefix asdocx_ and must have a unique template file name. In this template, we have given the name reg1. When we shall use this template, we shall invoke the template with the asdocx option of template(reg1). Each template must have a name that is not previously used. The template name must be without spaces, however, it can contain alpha-numeric characters.

Line 3-13:  Replace / append : These lines of code takes care of the replace / append options of asdocx. If a user uses the replace option, the macro $modifytype will contain the text replace, otherwise it will contain the text append. In case of replace, any previous files with a similar name as specified in the option save() will be deleted and the flexmat save location will be reset to 1. However, in the case of append, flexmat will find a next location to append the output from this template to the existing output.

Line 15-16:  flexmat addrow : From line 15, we start using the flexmat program. In line 15, we use the addrow sub-command to add the title row of the table. In the title row of the table, we write Variable , OR [95% CI], P-value using the data() option. The output table cells are separated by the use of comma i.e. “,”. If you have noticed, we did not specify the row number column number while writing this text to the flexmat table. The reason is that if we do not specify row and column numbers, the default is to use row(1) and col(1). Since we are writing three cells to the flexmat table, the starting point is row = 1 and col = 1, so in total three cells of the first row will contain the text Variable , OR [95% CI], P-value as shown in the following snapshot.

asdocx template

Line 17:  loc ThisRow 2 : In line 17, we define a local macro to contain the row number. The macro name is ThisRow. Since we wrote the column titles in row 1, se set ThisRow equal to 2 so that regression results are written from row 2 and onwards. As we move on, the row number will be incremented by value of one with the code `loc ++ThisRow'  as shown on line number 54.

Line 19:  `0′ : In line 19, execute the complete code that was passed on to the asdocx program. Since this template is for regression output, the code is likely to contain regression code, dependent and independent variables and some options. The macro  `0' contains everything that the user typed, excluding the keyword asdocx. Running this code, we not only get the results on the Stata screen, but also macros and matrices that are left behind the Stata regression commands. We can then get these useful bits of information to construct our own customized table.

Line 21:  loc dec 2 : Setting decimal points to 2

Line 22:  matrix table = r(table)  : To get the regression results stored in the r(table) and write them to matrix table

Line 23: local varnames : colfullnames table  : To get variable names

Line 24: local nvars : word count `varnames’  : To count number of variables / entries in the regression table

Line 26: local c = 1  : Macro c is used for column number, initially setting it equal to 1

Line 28: foreach v of local varnames { : This line marks the start of the foreach loop. The subsequent code in lines 30-57 loops over each variable in the regression.

Line 30-33: These lines get the regression coefficients from the matrix table that we obtained in line 22. Specifically:

Line 30: loc hzratio : dis %9.`dec’f = table[1, `c’] : gets the regression coefficients from the matrix table and sets the decimal points to macro dec that is 2

Line 31: loc ll : dis %9.`dec’f = table[5,`c’]’  : gets the lower limit of the 95% confidence interval

Line 32: loc ul : dis %9.`dec’f = table[6,`c’]’  : gets the upper limit of the 95% confidence interval

Line 33: loc pvalue: dis %9.`dec’f = table[4,`c’]’  : gets the p-value of the given coefficient