benjann / estout

Stata module to make regression tables
http://repec.sowi.unibe.ch/stata/estout/index.html
MIT License
71 stars 18 forks source link

Add markdown support to esttab #24

Closed ebardelli closed 3 years ago

ebardelli commented 4 years ago

Hi Ben,

I have been working on adding support for markdown output to esttab. I have run into some issues I was hoping you could help with.

Running this code:

sysuse auto
reg price trunk 
esttab, mmd style(mmd) title(A Markdown Table in Stata) nonumbers

produces this output:


A Markdown Table in Stata

|              |        price                  |
| ------------ | :---------------------------: |
| trunk        |        216.7<sup>\*\*</sup>   |
|              |       (2.81)                  |
| _cons        |       3183.5<sup>\*\*</sup>   |
|              |       (2.87)                  |
| *N*          |           74                  |

*t* statistics in parentheses
<sup>\*</sup> *p* < 0.05, <sup>\*\*</sup> *p* < 0.01, <sup>\*\*\*</sup> *p* < 0.001

which translates into a valid markdown table:

A Markdown Table in Stata

price
trunk 216.7**
(2.81)
_cons 3183.5**
(2.87)
N 74

t statistics in parentheses * p < 0.05, ** p < 0.01, *** p < 0.001

I have two issues:

  1. I couldn't pass the mmd style from esttab to estout to make it write the header row options. It looks like esttab automatically sets the style to esttab but the mmd style is required for the header row to be processed correctly.
  2. Adding two or more outputs to the header cells breaks the markdown tables because markdown expects only one header row. A workaround would be to separate each element in the header cells with <br> like this:
|              |        (1) <br> price         |
| ------------ | :---------------------------: |
| trunk        |        216.7<sup>\*\*</sup>   |
|              |       (2.81)                  |
| _cons        |       3183.5<sup>\*\*</sup>   |
|              |       (2.87)                  |
| *N*          |           74                  |
(1)
price
trunk 216.7**
(2.81)
_cons 3183.5**
(2.87)
N 74

I tried to look at the estout code that puts together the table headers but I couldn't make much progress in adjusting it.

Any guidance is much appreciated!

benjann commented 4 years ago

Issue 1: you can add option style(mmd) to esttab and it will pass it on to estout. However, esttab will also submit some other settings to estout that will probably screw up the markdown table. The closest I could get was with esttab, style(mmd) plain fixed delimiter(|), but the alignment of the horizontal line is off; don't know whether that will display properly in markdown. The problem is that there is no way (without changing the code of esttab.ado) to get rid of the delimiter() option that is always sent by esttab to estout. My suggestion: use estout to write the tables. Anything that esttab does can also be done in estout (at least in this context; there are some exceptions). To see the estout command that esttab puts together, add option noisily when calling esttab.

Issue 2: Maybe something like this?

estout m1 m2, style(mmd) collab(none) ///
    mlab("(1)<br>Model A" "(2)<br>Model B") ///
    modelwidth(16)
ebardelli commented 4 years ago

Thank you for following up.

I pushed a new commit to the pull request that fixes point (1) in my first post.

It turns out that point (2) is a not an estout issue. I was testing using pandoc which implements its own version of markdown that doesn't support multiline headers in tables. The official multimarkdown composer supports them. It should be up to the person using the table to figure out what their markdown composer supports and doesn't support.

You can see what I changed in esttab here. I added defaults for estout to write the markdown table. Running esttab with the mmd option or using a file with the extension .md or .mmd writes a table in markdown syntax.

For example:

. esttab, mmd title(A Markdown Table in Stata) noisily
estout ,
 cells(b(fmt(a3) star) t(fmt(2) par))
 stats(N, fmt(%18.0g) labels(`"*N*"'))
 starlevels(<sup>\*</sup> 0.05 <sup>\*\*</sup> 0.01 <sup>\*\*\*</sup> 0.001, label(" *p* < "))
 varwidth(12)
 modelwidth(12)
 begin(| )
 delimiter( | )
 end( |)
 title(A Markdown Table in Stata)
 prehead(`""' `"@title"' `""')
 posthead()
 prefoot()
 postfoot(`""' `"*t* statistics in parentheses"' `"@starlegend"' `""')
 varlabels(, end("" ) nolast)
 mlabels(, depvar)
 numbers
 collabels(none)
 eqlabels(,  nofirst)
 substitute(`"_ \_ "\_cons " \_cons"')
 interaction(" # ")
 level(95)
 style(mmd)

A Markdown Table in Stata

|              |          (1)                  |
|              |        price                  |
| ------------ | :---------------------------: |
| trunk        |        216.7<sup>\*\*</sup>   |
|              |       (2.81)                  |
| _cons        |       3183.5<sup>\*\*</sup>   |
|              |       (2.87)                  |
| *N*          |           74                  |

*t* statistics in parentheses
<sup>\*</sup> *p* < 0.05, <sup>\*\*</sup> *p* < 0.01, <sup>\*\*\*</sup> *p* < 0.001

or

. esttab using "test.md", title(A Markdown Table in Stata) noisily
estout using `"test.md"' ,
 cells(b(fmt(a3) star) t(fmt(2) par))
 stats(N, fmt(%18.0g) labels(`"*N*"'))
 starlevels(<sup>\*</sup> 0.05 <sup>\*\*</sup> 0.01 <sup>\*\*\*</sup> 0.001, label(" *p* < "))
 varwidth(12)
 modelwidth(12)
 begin(| )
 delimiter( | )
 end( |)
 title(A Markdown Table in Stata)
 prehead(`""' `"@title"' `""')
 posthead()
 prefoot()
 postfoot(`""' `"*t* statistics in parentheses"' `"@starlegend"' `""')
 varlabels(, end("" ) nolast)
 mlabels(, depvar)
 numbers
 collabels(none)
 eqlabels(,  nofirst)
 substitute(`"_ \_ "\_cons " \_cons"')
 interaction(" # ")
 notype
 level(95)
 style(mmd)
(output written to test.md)

with output to file:

A Markdown Table in Stata

|              |          (1)                  |
|              |        price                  |
| ------------ | :---------------------------: |
| trunk        |        216.7<sup>\*\*</sup>   |
|              |       (2.81)                  |
| _cons        |       3183.5<sup>\*\*</sup>   |
|              |       (2.87)                  |
| *N*          |           74                  |

*t* statistics in parentheses
<sup>\*</sup> *p* < 0.05, <sup>\*\*</sup> *p* < 0.01, <sup>\*\*\*</sup> *p* < 0.001
benjann commented 3 years ago

Hi Emanuele, I now added support for Markdown in -esttab- based on your suggested changes. See today's update. I am sorry it took so long.