Side-by-side regression tables
It’s often helpful to put the results from regression models in a side-by-side table so you can compare coefficients across different model specifications. If you’re unfamiliar with these kinds of tables, check out this helpful guide to how to read them.
We will use the huxreg() function in the huxtable package, the Palmer Penguins dataset, and a few regression models on trying to explain body_mass_g.
library(palmerpenguins)
model1 <- lm(body_mass_g ~ flipper_length_mm, data = penguins)
model2 <- lm(body_mass_g ~ flipper_length_mm + bill_length_mm, data = penguins)
model3 <- lm(body_mass_g ~ flipper_length_mm + bill_length_mm + species, data = penguins)
model4 <- lm(body_mass_g ~ flipper_length_mm + bill_length_mm + species + sex, data = penguins)
huxtable::huxreg()
Installing
huxtable is published on CRAN, so use the “Packages” panel in RStudio to install huxtable, or use:
install.packages("huxtable", dependencies = TRUE)
To knit to Word, you also need the flextable package, so install that too from the “Packages” panel, or use:
install.packages("flextable", dependencies = TRUE)
Using huxtable::huxreg() to knit to HTML and Word works very well.
Basic usage
As you go about building your linear models, you save them as object with different names, e.g., model1, model2, etc. Once you have the models you want to compare, pass them to huxreg():
library(huxtable)
huxreg(model1, model2, model3, model4)
| (1) | (2) | (3) | (4) | |
|---|---|---|---|---|
| (Intercept) | -5780.831 *** | -5736.897 *** | -3904.387 *** | -759.064 |
| (305.815) | (307.959) | (529.257) | (541.377) | |
| flipper_length_mm | 49.686 *** | 48.145 *** | 27.429 *** | 17.847 *** |
| (1.518) | (2.011) | (3.176) | (2.902) | |
| bill_length_mm | 6.047 | 61.736 *** | 21.633 ** | |
| (5.180) | (7.126) | (7.148) | ||
| speciesChinstrap | -748.562 *** | -291.711 *** | ||
| (81.534) | (81.502) | |||
| speciesGentoo | 90.435 | 707.028 *** | ||
| (88.647) | (94.359) | |||
| sexmale | 465.395 *** | |||
| (43.081) | ||||
| N | 342 | 342 | 342 | 333 |
| R2 | 0.759 | 0.760 | 0.822 | 0.871 |
| logLik | -2528.427 | -2527.741 | -2476.373 | -2359.787 |
| AIC | 5062.855 | 5063.482 | 4964.745 | 4733.574 |
| *** p < 0.001; ** p < 0.01; * p < 0.05. | ||||
You can add column names, to make the output table more user friendly.
huxreg(list("A" = model1, "B" = model2, "C" = model3, "D" = model4))
| A | B | C | D | |
|---|---|---|---|---|
| (Intercept) | -5780.831 *** | -5736.897 *** | -3904.387 *** | -759.064 |
| (305.815) | (307.959) | (529.257) | (541.377) | |
| flipper_length_mm | 49.686 *** | 48.145 *** | 27.429 *** | 17.847 *** |
| (1.518) | (2.011) | (3.176) | (2.902) | |
| bill_length_mm | 6.047 | 61.736 *** | 21.633 ** | |
| (5.180) | (7.126) | (7.148) | ||
| speciesChinstrap | -748.562 *** | -291.711 *** | ||
| (81.534) | (81.502) | |||
| speciesGentoo | 90.435 | 707.028 *** | ||
| (88.647) | (94.359) | |||
| sexmale | 465.395 *** | |||
| (43.081) | ||||
| N | 342 | 342 | 342 | 333 |
| R2 | 0.759 | 0.760 | 0.822 | 0.871 |
| logLik | -2528.427 | -2527.741 | -2476.373 | -2359.787 |
| AIC | 5062.855 | 5063.482 | 4964.745 | 4733.574 |
| *** p < 0.001; ** p < 0.01; * p < 0.05. | ||||
Statistics to display, bold significant variables, add captions
You can choose what statistics to display; for instance, if we wanted to show number of observation, R^2 and adjusted R2, and the residual SE, we pass them to the statistics variable. We can also bold those variables that are significant at, say 0.05, and choose not to use stars to denote level of significance by using stars = NULL.
huxreg(model1, model2, model3,
statistics = c('#observations' = 'nobs',
'R squared' = 'r.squared',
'Adj. R Squared' = 'adj.r.squared',
'Residual SE' = 'sigma'),
bold_signif = 0.05,
stars = NULL
) %>%
set_caption('Comparison of models')
| (1) | (2) | (3) | |
|---|---|---|---|
| (Intercept) | -5780.831 | -5736.897 | -3904.387 |
| (305.815) | (307.959) | (529.257) | |
| flipper_length_mm | 49.686 | 48.145 | 27.429 |
| (1.518) | (2.011) | (3.176) | |
| bill_length_mm | 6.047 | 61.736 | |
| (5.180) | (7.126) | ||
| speciesChinstrap | -748.562 | ||
| (81.534) | |||
| speciesGentoo | 90.435 | ||
| (88.647) | |||
| #observations | 342 | 342 | 342 |
| R squared | 0.759 | 0.760 | 0.822 |
| Adj. R Squared | 0.758 | 0.759 | 0.820 |
| Residual SE | 394.278 | 394.068 | 340.114 |
Warning 1: huxtable reformats all your tables
If your document creates any other tables (like with tidy()), huxtable automatically formats these tables in a fancy way. If you don’t want that, you can turn it off with this code—put it at the top of your document near where you load your libraries:
# Huxtable likes to automatically format *all* tables, which is annoying.
# This turns that off.
options('huxtable.knit_print_df' = FALSE)
Warning 2: Knitting to PDF is fragile
In order to knit to PDF, you need to install LaTeX, which you should have done when you installed tinytex. When using huxtable, before knitting to PDF for the first time on your computer, you need to run this in your console to install the LaTeX packages that R uses to knit huxtable tables to PDF:
huxtable::install_latex_dependencies()
If you’re using tinytex, you’ll also need to run this once on your computer:
tinytex::tlmgr_install("unicode-math")