knitr::opts_chunk$set( collapse = TRUE, comment = "", message = FALSE, warning = FALSE ) library(stargazer2)
stargazer2 is a drop-in replacement for the stargazer package with native
support for modern econometrics packages. For lm objects the output is
designed to be identical to the original, with one key addition: the standard
error type is always identified in the table note.
The primary output format is "latex" for embedding in papers. "text"
provides a quick terminal preview without needing to compile anything.
We use the wage1 dataset from the wooldridge package throughout this
vignette. Three categorical variables are constructed from existing binary
indicators.
library(wooldridge) data(wage1) wage1$region <- factor( ifelse(wage1$northcen == 1, "northcen", ifelse(wage1$south == 1, "south", ifelse(wage1$west == 1, "west", "northeast"))), levels = c("northeast", "northcen", "south", "west") ) wage1$occupation <- factor( ifelse(wage1$profocc == 1, "professional", ifelse(wage1$clerocc == 1, "clerical", ifelse(wage1$servocc == 1, "service", "other"))), levels = c("other", "professional", "clerical", "service") ) wage1$industry <- factor( ifelse(wage1$construc == 1, "construction", ifelse(wage1$ndurman == 1, "nondurable_manuf", ifelse(wage1$trcommpu == 1, "transport", ifelse(wage1$trade == 1, "trade", ifelse(wage1$services == 1, "services", ifelse(wage1$profserv == 1, "prof_services", "other")))))), levels = c("other", "construction", "nondurable_manuf", "transport", "trade", "services", "prof_services") )
Four progressively richer log-wage specifications:
m1 <- lm(lwage ~ educ + exper + tenure, wage1) m2 <- lm(lwage ~ educ + exper + tenure + female + married, wage1) m3 <- lm(lwage ~ educ + exper + tenure + female + married + region + occupation, wage1) m4 <- lm(lwage ~ educ + exper + tenure + female + married + region + occupation + industry, wage1)
A single call produces a publication-ready table. Models 3 and 4 include
factor variables; omit suppresses their level dummies so the table stays
focused on the economic variables of interest.
stargazer(m1, m2, m3, m4, type = "text", title = "Determinants of Log Wages", dep.var.labels = "log(Wage)", covariate.labels = c("Education", "Experience", "Tenure", "Female", "Married"), omit = c("region", "occupation", "industry"), column.labels = c("Baseline", "Demographics", "Region/Occ.", "Full"), notes.append = FALSE, notes = "Controls for region, occupation, and industry in (3) and (4).")
The LaTeX source is what goes directly into your .tex file or via
\input{}. Write to a file with out = "table.tex".
stargazer(m1, m2, type = "latex", title = "Determinants of Log Wages", label = "tab:wage-ols", dep.var.labels = "log(Wage)", covariate.labels = c("Education", "Experience", "Tenure"))
For use in R Markdown documents where a rendered table is more readable than LaTeX source:
stargazer(m1, m2, type = "html", dep.var.labels = "log(Wage)", covariate.labels = c("Education", "Experience", "Tenure"))
vcovThe vcov argument accepts a list of variance-covariance matrices — one per
model. stargazer2 extracts the square root of the diagonal internally and
updates the table note to name the SE type used in each column. This works
with any function returning a matrix: sandwich::vcovHC, sandwich::vcovCL,
or your own estimator.
library(sandwich) stargazer(m1, m2, m3, m4, type = "text", dep.var.labels = "log(Wage)", covariate.labels = c("Education", "Experience", "Tenure", "Female", "Married"), omit = c("region", "occupation", "industry"), vcov = list(vcovHC(m1, type = "HC1"), vcovHC(m2, type = "HC1"), vcovHC(m3, type = "HC1"), vcovHC(m4, type = "HC1")))
stargazer(m1, m2, m3, m4, type = "text", dep.var.labels = "log(Wage)", covariate.labels = c("Education", "Experience", "Tenure", "Female", "Married"), omit = c("region", "occupation", "industry"), vcov = list(vcovCL(m1, cluster = ~industry, data = wage1), vcovCL(m2, cluster = ~industry, data = wage1), vcovCL(m3, cluster = ~industry, data = wage1), vcovCL(m4, cluster = ~industry, data = wage1)))
vcov entries need not be the same type across columns. When SE types differ,
the note reports them by column group. Here column (1) uses HC1-robust SEs
while columns (2)–(4) use industry-clustered SEs.
stargazer(m1, m2, m3, m4, type = "latex", dep.var.labels = "log(Wage)", covariate.labels = c("Education", "Experience", "Tenure", "Female", "Married"), omit = c("region", "occupation", "industry"), column.labels = c("Baseline", "Demographics", "Region/Occ.", "Full"), vcov = list(vcovHC(m1, type = "HC1"), vcovCL(m2, cluster = ~industry, data = wage1), vcovCL(m3, cluster = ~industry, data = wage1), vcovCL(m4, cluster = ~industry, data = wage1)))
The most commonly used formatting arguments:
| Argument | Purpose |
|---|---|
| dep.var.labels | Override dependent variable name(s) |
| covariate.labels | Rename coefficient rows (in display order) |
| column.labels | Column headers beneath the dep-var line |
| omit / keep | Regex patterns to drop or retain coefficient rows |
| digits | Decimal places for all numbers |
| star.cutoffs | P-value thresholds for significance stars |
| notes / notes.append | Add or replace the automatic table note |
| title / label | Caption and \label{} for LaTeX |
The style argument selects a layout preset.
| Style | Layout | Significance note |
|---|---|---|
| "stargazer2" | Single \hline, full-width left-aligned note | p-value thresholds (default) |
| "stargazer" | Matches original package exactly (double rules, \\[-1.8ex]) | p-value thresholds |
| "aer" | American Economic Review — clean, no dep-var caption | Text descriptions ("Significant at the X percent level") |
| "qje" | Quarterly Journal of Economics — like AER; observations labelled $N$ | Text descriptions |
stargazer(m1, m2, type = "latex", dep.var.labels = "log(Wage)", covariate.labels = c("Education", "Experience", "Tenure"), style = "stargazer2") # default
stargazer(m1, m2, type = "latex", dep.var.labels = "log(Wage)", covariate.labels = c("Education", "Experience", "Tenure"), style = "aer")
Passing a data frame instead of model objects produces a summary statistics table.
stargazer( wage1[, c("lwage", "educ", "exper", "tenure", "female", "married")], type = "text", covariate.labels = c("log(Wage)", "Education", "Experience", "Tenure", "Female", "Married") )
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.