## Introduction
As an economist working as a research assistant, I would hold that producing tables with estimation results is one of the job's main tasks. As the research project flows, the results change, and as a consequence, the tables. With this in mind, the importance of maintaining the tables pipeline automatized is a crucial task. In the first place, you avoid typing errors due to manual typing, and most importantly, you prevent manually typing a table hand. Second, when you have a code to make the results for you, your results are reproducible. This issue is important to share the code with other researchers, as well as your future self.
In this post, I will show how to achieve amazing automatized regression tables using the R package called `stargazer`. This fantastic package (which name is also an incredible song written by [Rainbow](https://youtu.be/rVXy1OhaERY){:target="_blank"}) produce table outputs with the data objects that are outputs of your estimations. Almost every detail of the tables is customizable!
## Using `stargazer`
### Data set
According to the documentation, `swiss` data contains "*Standardized fertility measure and socio-economic indicators for each of 47 French-speaking provinces of Switzerland at about 1888*". You can find more details [here](https://stat.ethz.ch/R-manual/R-devel/library/datasets/html/swiss.html){:target="_blank"}.
```{r Dataset}
data('swiss')
head(swiss)
```
### Basic Usage
We will use a Linear Regression model to explain how Fertility is affected by several variables for explanatory purposes. Of course, `stargazer` supports a broader set of packages, including Instrumental Variables, Fixed Effects Models, among many others. Check the [supported models](https://rdrr.io/cran/stargazer/man/stargazer_models.html){:target="_blank"} to see all the possibilities. Finally, I will format all the tables in `html` to show the outputs. In the last part of this post, I will show how to use `LaTeX` outputs.
**Disclaimer**: I intend to show how to draw tables using `stargazer`, so do not expect too much from these models.
```{r Model}
model_1 <- lm(Fertility ~ Catholic + Infant.Mortality, data = swiss)
model_2 <-
lm(Fertility ~ Catholic + Infant.Mortality + Agriculture, data = swiss)
model_3 <-
lm(Fertility ~ Catholic + Infant.Mortality + Agriculture + Examination,
data = swiss)
# Checking a summary
summary(model_1)
```
The package is straightforward to use. As we see in the example, just passed the objects with the estimation parameters to the table, and you will have an excellent output.
```{r Default Option, results='asis', warning=FALSE, message=FALSE}
# install.packages('stargazer')
library(stargazer)
stargazer(model_1, model_2, model_3, type = "html")
```
### Editing Headers
Of course, your requirements will vary depending on which results do you want to show. Within this function, you have many options to format the header of your table. Here I present some features that you can modify (`dep.var.caption`, `dep.var.labels`, `column.labels`, `dep.var.labels.include`, `model.numbers`), but there are many more!
```{r Editing Headers - Change models labels, results='asis'}
stargazer(
model_1,
model_2,
model_3,
type = "html",
dep.var.caption = "My new caption",
dep.var.labels = "Fertility (Live births per 1,000 inhabitants)",
column.labels = c("OLS", "OLS", "OLS"),
dep.var.labels.include = TRUE,
# By default is TRUE, change to FALSE to supress the dep var labels,
model.numbers = TRUE
# By default is TRUE, change to FALSE to supress models' numbers.
)
```
#### Multicolumns
You can arrange the `column.labels` array to work with multicolumn using `column.separate`.
For instance, in econometrics, it is common to use the column labels to reference the estimation strategy used to estimate a set of coefficients. Imagine that you are working on the same three models presented above, with the difference that you are estimating the third one with *Instrumental Variables* (IV) approach instead of *Ordinary Least Squares* (OLS).
```{r Editing Headers - Multicolumn in col labels, results='asis'}
stargazer(
model_1,
model_2,
model_3,
type = "html",
column.labels = c("OLS", "IV"),
column.separate = c(2, 1)
# First label for the first two columns and the second for the third one
)
```
### Changing Covariates' Labels
Change the covariate labels is also super easy. Just pass an array with your desired titles to the parameter `covariates.labels`. My suggestion is that you ALWAYS must check the order of the features used in an estimation model because you could wrongly label a variable with another name.
```{r Changing Covariates Labels, results='asis'}
labels <- c(
'Catholic (% as opposed to protestant)',
'Infant Mortality *live births who live less than 1 year)',
'Agriculture (% of males involved in agriculture as occupation',
'Examination (% draftees receiving highest mark on army examination)'
)
stargazer(model_1,
model_2,
model_3,
type = "html",
covariate.labels = labels)
```
### Styles
This package has a parameter to configure the table's custom according to several academic journals' aesthetics. For example, in the model below, I present a table with *American Economic Review* style. You can check all the options at this [link](https://rdrr.io/cran/stargazer/man/stargazer_style_list.html){:target="_blank"}.
```{r Styles, results='asis', warning=FALSE, message=FALSE}
stargazer(model_1, model_2, model_3, type = "html", style='aer')
```
### Customizing Stats of the Table
You can customize how to present the coefficients and the statistical inference using the `report` parameter. In my opinion, the syntax of this parameter a little tricky. Here are two examples of how to modify this feature:
```{r Editing Stats of the Table - Parenthesis Paramenters, results='asis'}
# rep_format <- "vcp*" # variable name, coefficient, p value and stars
rep_format <- "vct" # variable name, coefficient, t statistic without stars
stargazer(model_1,
model_2,
model_3,
type = "html",
report = rep_format)
```
### Using personalized standard errors and p-values
In general, a best practice while estimating linear models is to use robust standard errors since the good asymptotic properties allow us to improve the estimation's statistical inference.
For `Stata` users, the option `, r` at the end of every regression performs this task. Unfortunately, in R, the [approach](https://www.r-econometrics.com/methods/hcrobusterrors/){:target="_blank"} is not as direct as in `Stata` to use these errors. Nonetheless, `stargazer` allow us to use customized standard errors and p-values for our tables.
```{r Editing Stats of the Table - Using personalized standard errors and p-values, results='asis', warning=FALSE, message=FALSE}
# install.packages('lmtest')
# install.packages('sandwich')
library("lmtest") # coeftest
library("sandwich") # vcovHC
# Robust standard errors:
# Check https://www.r-econometrics.com/methods/hcrobusterrors/ for more details/
inference_m1 <-
coeftest(model_1, vcov = vcovHC(model_1, type = "HC0"))
inference_m2 <-
coeftest(model_2, vcov = vcovHC(model_2, type = "HC0"))
inference_m3 <-
coeftest(model_3, vcov = vcovHC(model_3, type = "HC0"))
stargazer(
model_1,
model_2,
model_3,
se = list(NULL, inference_m2[, 2], inference_m3[, 2]), # If NULL use model_* errors
p = list(NULL, inference_m2[, 4], inference_m3[, 4]), # If NULL use model_* pvalues
omit.stat = "f",
type = "html"
)
```
### Customizing Footer Stats
Of course, you don't need to show always the same indicators in every table. With the option `keep.stat`, you can specify an array of statistics to show in your table. In this example, I only show the sample size and the R-squared. You can check the [list of statistics](https://www.rdocumentation.org/packages/stargazer/versions/5.2.2/topics/stargazer_stat_code_list){:target="_blank"} here!
```{r Editing Footer and Notes - Footer stats, results='asis'}
stargazer(
model_1,
model_2,
model_3,
type = "html",
keep.stat = c("n", "rsq")
)
```
### Adding new lines
In some context, it is helpful to add lines at the end of the table. For example, when using Fixed Effects, it is common to see an array indicating if an estimation is controlling for some Fixed Effect or not. From my perspective, the best way to achieve this is to use the `add.lines` option. Here, you specify a list of arrays with all the lines that you want to add.
```{r Editing Footer and Notes - Adding lines, results='asis'}
stargazer(
model_1,
model_2,
model_3,
type = "html",
keep.stat = c("n", "rsq"),
add.lines = list(
c("County Fixed Effect", "No", "Yes", 'Yes'),
c("Time Fixed Effect", "Yes", "No", 'Yes')
)
)
```
### Customizing Notes
I wouldn't say I like this option very much because the notes are introduced in a multicolumn, affecting the table's width depending on the notes' length. Nevertheless, I leave some examples of how to customize them.
```{r Editing Footer and Notes - Editing Notes, results='asis'}
stargazer(
model_1,
model_2,
model_3,
type = "html",
keep.stat = c("n", "rsq"),
add.lines = list(
c("County Fixed Effect", "No", "Yes", 'Yes'),
c("Time Fixed Effect", "Yes", "No", 'Yes')
),
notes.label = 'Comments', # Edit here the label
notes = 'Own elaboration based on swiss data. Significance levels: * 90%, ** 95%, *** 99%.',
notes.append = FALSE, # TRUE append the significance levels
notes.align = 'l' # c center, r right
)
```
### Stargazer and LaTeX
`stargazer` and `LaTeX` are a great combination together! Change the parameter `type` to `"latex"` and the package will do the work for you. You can also save the output in an external file specifying the parameter `out`. Additionally, if you don't want your table in the `table` environment (i.e. you just want the `tabular`), use the option `float`. In future posts, I will go deeper on this issue.
```{r Stargazer and LaTeX - Editing Notes, warning=FALSE, message=FALSE}
stargazer(
model_1,
model_2,
model_3,
type = "latex",
# out = 'path/of/your/table.tex'
header = FALSE, # If TRUE, stargazer print the header with the citation and package info
float = TRUE # If FALSE, the function don't returns the table in a table environment
)
```
## Final Thoughts
I found `stargazer` a terrific tool for scientific research. It is intuitive to use and is highly customizable. There is also a `python` [version](https://pypi.org/project/stargazer/){:target="_blank"} under development!
I hope this post will help you with your tables! :)
## References
- [`stargazer`: beautiful LATEX, HTML and ASCII tables from R statistical output](https://cran.r-project.org/web/packages/stargazer/vignettes/stargazer.pdf){:target="_blank"}
- [A Stargazer Cheatsheet](https://www.jakeruss.com/cheatsheets/stargazer/){:target="_blank"}
- [`stargazer` function - RDocumentation](https://www.rdocumentation.org/packages/stargazer/versions/5.2.2/topics/stargazer){:target="_blank"}
- [Heteroskedasticity Robust Standard Errors in R](https://www.r-econometrics.com/methods/hcrobusterrors/){:target="_blank"}
- [stargazer_models: `stargazer`: list of supported objects](https://rdrr.io/cran/stargazer/man/stargazer_models.html){:target="_blank"}