`etable` in `fixest` package — how to make an AER paper regression table

Common Used package in R

  1. xtable: plain tex
  2. kableExtra: dataframe as tex table
  3. fixest: further with frequent latex options

Concept of fixest

  1. fixest provides sw (stepwise) and csw (cumulative stepwise) function for regression formula
    -> Pros: do not need to write regressions in separate lines
    -> Cons: convenient for nested models, not for general purposes
  2. use feols (fixed effect OLS) to estimate regression models (create fixest model objects)
    We can still make one model one regression as we wish to.
  3. use etable (estimation table) to export regression output into dataframe or tex format.

Example

est1 <- feols(sw(prc, LNprc_hh, prc_banks, prc_inve, prc_insu, prc_mut, prc_pens) ~ be_s + ebit_s | fdate, # fixed effect: fdate 
              data=main_data, cluster = ~fdate) # cluster se by fdate
etable(est1,
       tex = TRUE,
       postprocess.tex = setLineWidth, linewidth = TRUE,
       style.tex = style.tex(main = "aer",                          # main style
                             line.top = "\\midrule",                   # single line or double lines
                             line.bottom = "\\midrule",                # on the top or the bottom
                             var.title = "\\midrule",               # default is "\midrule \emph{Variables}"
                             model.title = "",                      # default is "Model:"
                             depvar.title = "Dependent Variable:", #
                             fixef.title = "\\midrule",             # Since we only have one fixed effect to note, we add a separate line here
                             yesNo = c("Quarter", "No"),               # cells to display in the fixed effect
                             fixef.prefix = "",                     #
                             fixef.suffix = "",                     #
                             fixef.where = "var",                   # "var" after the variables; "stats" after R^2
                             # tablefoot = TRUE,
                             # tablefoot.value = footnote,
                             tabular = "X"                          # use tabular* or tabularx if X
       ),

       style.df = style.df(depvar.title = "Dependent Variable: ", 
                             yesNo = c("Quarter", "No"),
                             fixef.prefix = "",
                             fixef.suffix = "",
                             ))
  • We want to estimate 7 regression models, and the only difference is the dependent variable.
  • The vertical bar inside the formula indicates the fixed effect indicator.
  • style.tex controls the output when tex = T, and style.df controls the output when tex = F

Postprocess tex

  • postprocess.tex can handle the plain tex output (only when tex = T) with a self-defined function. For example, if I want the output table to have linewidth option instead of textwidth, I can simply define a function below to override the original table width option.
# change the `\textwidth` argument into `\linewidth` in LaTeX
# to better adjust the table width with tabularx environment
setLineWidth <- function(x, linewidth = TRUE) {
  # x is the char vector returned by etable
  if (linewidth) {
    # change \begin{tabularx}{\textwidth}{xXXXXXXX}
    x <- stringr::str_replace(x, ("textwidth"), ("linewidth"))
    # make the first column l
    x <- stringr::str_replace(x, "XXXXXXXX", "lXXXXXXX")
  }
  return(x)
}

Variable Naming Dictionary

variable naming is always a hassle when outputting tables. Thanks to fixest and its clever design, we can easily set up a variable naming mapping with setFixest_dict

# Setting a dictionary 
keyvalues <- c(prc = "PRC",
               LNprc_hh = "Households",
               prc_banks = "Banks",
               prc_inve = "Investment company",
               prc_insu = "Insurance company",
               prc_mut = "Mutual funds", 
               prc_pens = "Pension funds",
               be_s = "Book 
               equity",
               ebit_s = "OP" ,
               beta = "\\beta",
               fdate = "Fixed \\\ Effect"
               )
setFixest_dict(keyvalues)

Number of digits

We can restrict the output to always display 4 digits

# make the table alawys display four digits
setFixest_etable(digits = "r4", digits.stats = "r4")

See this github issue for more information.
https://github.com/lrberge/fixest/issues/82

Output after rendered from tex

Then we have the following table

Integrate with RSweave (.Rnw files)

Below are the pseudo-codes for integrating the fixest outputs and RSweave.

<<setup, echo = FALSE, results= 'hide', message = FALSE, warning = FALSE, include=FALSE>>=


library(fixest) # used for fixed effect estimation and exporting tables

data <- load(...)
@

% Below are latex codes
\Sexpr{ifelse(is_tab_landscape, beg_landscape_str, "")}

\begin{table}[h]

\begin{adjustwidth}{-48pt}{-48pt}

\singlespacing
\footnotesize


\Sexpr{shift_table_vspace}

\caption{\small \Sexpr{tab_title}}
\label{\Sexpr{tab_label}}

{\noindent
  \Sexpr{tab_topline}
}

\centering

\bigspace

<<tab, echo = FALSE, results = 'asis', message = FALSE, warning = FALSE>>=

# Create tables with fixest::etable()

# Setting a dictionary 
keyvalues <- c(y = "wage",
               educ = "education",
               fss = "family social status",
               state = "residental state",
               year = "year recorded"
               )
setFixest_dict(keyvalues)

# make the table alawys display four digits
setFixest_etable(digits = "r4", digits.stats = "r4")

# change the `\textwidth` argument into `\linewidth` in LaTeX
# to better adjust the table width with tabularx environment
setLineWidth <- function(x, linewidth = TRUE) {
  # x is the char vector returned by etable
  if (linewidth) {
    # change \begin{tabularx}{\textwidth}{xXXXXXXX}
    x <- stringr::str_replace(x, ("textwidth"), ("linewidth"))
    # make the first column l
    x <- stringr::str_replace(x, "XXXXXXXX", "lXXXXXXX")
  }
  return(x)
}

est1 <- feols(y ~ educ + fss | csw0(state, year), # fixed effect: fdate 
              data = data, cluster = ~state) # cluster se by fdate
etable(est1,
       tex = TRUE,
       postprocess.tex = setLineWidth, linewidth = TRUE,
       style.tex = style.tex(main = "aer",
                             var.title = "\\midrule",
                             depvar.title = "Dependent Variable:",
                             yesNo = c("Yes", "No"),
                             tabular = "X"
                             ),       
       style.df = style.df(depvar.title = "Dependent Variable: ", 
                             yesNo = c("Yes", "No"),
                             fixef.prefix = "",
                             fixef.suffix = "",
                             ))

@


\end{adjustwidth}

\end{table}

\Sexpr{ifelse(is_tab_landscape, end_landscape_str, "")}

Reference

  • tutorial for etable:
    • https://cran.r-project.org/web/packages/fixest/vignettes/exporting_tables.html
  • display coefficient digits in etable
    • https://github.com/lrberge/fixest/issues/82
  • Make table wider in tabularx
    • https://tex.stackexchange.com/questions/415440/make-tabularx-wider-than-textwidth-pt-values#:~:text=I%20would%20go%20the%20simple,increasing%20the%20width%20by%20xpt%20
  • Another fixest tutorial
    • https://www.patrickbaylis.com/blog/2021-05-30-making-tables/
  • Documentation of fixest
    • https://cran.r-project.org/web/packages/fixest/fixest.pdf
  • What is I lost some .sty files?
    • https://bookdown.org/yihui/rmarkdown-cookbook/install-latex-pkgs.html
# or use the `text` argument
tinytex::parse_packages(
  text = "! LaTeX Error: File `ocgbase.sty' not found."
)

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *