Stargazer Notes Line Wrap

Formatting notes in R's stargazer tables

stargazer returns its output invisibly as a character vector, specifically so you can post-process it. Depending what you want to change, this may involve some regex. Or, as in this case, if you know what your notes line should look like, you can simply replace the wrong line with what you want. Here's a minimal reproducible example:

df <- data.frame(x = 1:10 + rnorm(100),
y = 1:10 + rnorm(100))
reg <- lm(y ~ x, data = df)

star <- stargazer(reg,
style = "qje", notes.append = FALSE, notes.align = "l",
notes = "This will be replaced")

note.latex <- "\\multicolumn{5}{l} {\\parbox[t]{11cm}{ \\textit{Notes:} Logistic regression. Dependent variable: an indicator varible ... AND Some very long and interesting comment.}} \\\\"
star[grepl("Note",star)] <- note.latex
cat (star, sep = "\n")

Including notes on stargazer table distorts distance between columns

LaTeX solution

I had a similar issue, and here's my solution for LaTeX.

First, you need a separate function that creates its own minipage where the note is included.

library(stargazer)

stargazernote <- function(starGazerCmd, outputfile, note){
# inserts 'note' to the end of stargazer generated latex table
ssn <- gsub(x=starGazerCmd, pattern='\\end{tabular}',
replacement=paste('\\end{tabular}', '\n',
'\\centerline{\\begin{minipage}{0.95\\textwidth}~\\', '\n',
'\\footnotesize{' , note,
'} \\end{minipage}}', sep=''), fixed=T)

cat(ssn,sep='\n',file=outputfile)
}

(You might want to play around with the parameter {0.95\\textwidth}. Some people like slightly wider or narrower width for their notes.)

Create your stargazer latex table without the note as follows:

s <- stargazer(data,
type = "latex",
style = "AER",
notes.append=FALSE,
)

Then create the note separately:

note <- "All models were estimated by fixed effects estimator. Errors are robust to heteroscedasticity and autocovariance. Numbers between parenthesis are the coefficient standard deviations. * represents significance at the 10 \\% level, ** represents significance at the 5\\% level, and *** represents significance at the 1\\% level. Models (1), (2) and (3) refer, respectively, to equations (7), (8) and (9)"

Here's a first gotcha: the % sign is interpreted as a comment symbol by LaTeX, so you need to escape your %'s by prepending them with \\.

Now you can use the function above to collate the note and the LaTeX table:

stargazernote(s, note=note, outputfile='foo.tex')

The output looks like this: Sample Image

The second gotcha is that you need to remember to include graphicx in your LaTeX file. Here's what a .tex file might look like:

\documentclass[english]{article}
\usepackage[T1]{fontenc}
\usepackage[latin9]{inputenc}

\usepackage{graphicx} %% note: the table will not render without this package.

\begin{document}
\include{foo.tex}
\end{document}

Text solution

You can force line changes in notes like this (this is copied from this SO question):

stargazer(data,
type = "text",
notes= c("All models were estimated by fixed effects estimator.",
"Errors are robust to heteroscedasticity and autocovariance.",
"Numbers between parenthesis are the coefficient standard deviations.",
"* represents significance at the 10 % level",
"** represents significance at the 5% level,",
"and *** represents significance at the 1% level.",
"Models (1), (2) and (3) refer, respectively, to equations (7), (8) and (9)"),
style = "AER")

Output:

=================================================================================
Statistic N Mean St. Dev. Min Pctl(25) Pctl(75) Max
---------------------------------------------------------------------------------
V1 7 0.184 0.380 -0.230 -0.004 0.231 0.957
V2 7 -0.083 1.018 -1.246 -0.827 0.631 1.322
V3 7 -0.058 0.752 -0.733 -0.610 0.495 1.025
V4 7 -0.316 1.106 -2.223 -0.725 0.412 1.120
V5 7 -0.242 0.927 -1.777 -0.809 0.397 0.743
V6 7 -0.020 1.403 -1.453 -1.202 0.756 2.348
V7 7 0.565 1.130 -1.459 0.156 1.224 2.023
V8 7 0.840 0.938 -0.493 0.334 1.302 2.256
V9 7 -0.191 0.761 -1.012 -0.766 0.236 1.107
V10 7 0.530 0.643 -0.222 0.144 0.680 1.768
V11 7 0.263 0.396 -0.230 -0.004 0.432 0.957
---------------------------------------------------------------------------------
All models were estimated by fixed effects estimator.
Errors are robust to heteroscedasticity and autocovariance.
Numbers between parenthesis are the coefficient standard deviations.
* represents significance at the 10 % level
** represents significance at the 5% level,
and *** represents significance at the 1% level.
Models (1), (2) and (3) refer, respectively, to equations (7), (8) and (9)

Add a row with notes using stargazer

stargazer(linear.1, linear.2, type="text", keep.stat=c("n"),  
add.lines=list(c("Note 1", "X", ""), c("Note 2", "", "X")))

Does the trick.

Stargazer column on multiple lines *with multiple models*?

Ok, my apologies, I was really close, I should have looked a little harder before posting. The key was 1) to use \shortstack instead of \mbox and 2) not to escape the { characters.

var1<-rnorm(100)
var2<-rnorm(100)
df<-data.frame(var1, var2)
mod<-lm(var1~var2)
library(stargazer)
stargazer(mod, mod, column.labels=c('\\shortstack{my models \\\\ need long titles}',
'\\shortstack{my models \\\\ need long titles}'))

Sample Image

Getting Stargazer Column labels to print on two or three lines?

One option: You can insert latex codes for newline (\\) and table column alignment (&). Note that each \ needs to be "escaped" in R with another \.

stargazer(mod, column.labels='my models\\\\ & need long titles')

Sample Image

Another way is to multirow. This could be easier for more complex tables with different length headings on each column. You will need to add \usepackage{multirow} to your document preamble.

stargazer(mod, column.labels='\\multirow{2}{4 cm}{my models need long titles}')

You will also need to post-edit the latex output from stargazer to insert some extra lines (using \\) below the variable headings so that the rest of the table gets moved down also (as in the exceprt below):

& \multirow{2}{4 cm}{my models need long titles} \\ 
\\ % note the extra line inserted here before the horizontal rule
\hline \\[-1.8ex]

Sample Image

Add line with datasets at top of table (stargazer R package)

In the stargazer() function, the row you refer to is governed by the dep.var.caption option. Unfortunately, since you want more than one column in this row, you can't accomplish what you want without some tinkering; if you pass a vector of length > 1 to this option, stargazer() will throw an error. So, we'll have to make a custom function that captures the output from stargazer() and modifies it accordingly before printing it.

The following .Rmd file worked fine for me (output below the code):

---
title: "Stack Overflow Answer"
author: "duckmayr"
date: "November 3, 2017"
output: pdf_document
---

```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
```

```{r, echo=FALSE}
custom_table <- function(dataset_labels, ...) {
tbl <- capture.output(stargazer::stargazer(...))
pattern1 <- 'Dependent variable:'
pattern2 <- '(?<= \\& ).+(?= \\\\)'
first_row_index <- which(grepl(pattern=pattern1, x=tbl))
first_row <- tbl[first_row_index]
colspan <- as.numeric(gsub(pattern='[^0-9]+', replacement='', first_row))
colspan <- colspan / length(dataset_labels)
new_first_row <- sub('[0-9]+', colspan, first_row)
replacement <- rep(stringr::str_extract(new_first_row, pattern2), 2)
replacement <- stringr::str_replace(replacement, pattern1, dataset_labels)
replacement <- paste(replacement, collapse=' & ')
new_first_row <- stringr::str_replace(new_first_row, pattern2, replacement)
new_first_row <- stringr::str_replace_all(new_first_row, 'multi', '\\\\multi')
new_first_row <- stringr::str_replace_all(new_first_row, 'textit', '\\\\textit')
tbl[first_row_index] <- new_first_row
cat(tbl, sep='\n')
}
swiss2 <- swiss[1:20,]
m1 <- lm(Fertility ~ Agriculture, data = swiss)
m2 <- lm(Fertility ~ Examination, data = swiss)
m3 <- lm(Infant.Mortality ~ Education, data = swiss)
m4 <- lm(Infant.Mortality ~ Catholic, data = swiss)
m5 <- lm(Fertility ~ Agriculture, data = swiss2)
m6 <- lm(Fertility ~ Examination, data = swiss2)
m7 <- lm(Infant.Mortality ~ Education, data = swiss2)
m8 <- lm(Infant.Mortality ~ Catholic, data = swiss2)
```

```{r, echo=FALSE, results='asis'}
custom_table(c('Data: Swiss', 'Data: Swiss2'),
m1, m2, m3, m4, m5, m6, m7, m8,
type = "latex",
header=FALSE,
omit.stat=c("LL","ser","f","adj.rsq"),
font.size="tiny",
column.labels = c("(M1)", "(M2)", "(M3)", "(M4)", "(M5)", "(M6)", "(M7)", "(M8)"),
model.names = FALSE,
model.numbers = FALSE,
star.cutoffs = c(0.05, 0.01, 0.001),
dep.var.labels = c("Outcome 1", "Outcome 2", "Outcome 1", "Outcome 2"))
```

Sample Image

EDIT:

If you'd prefer the output to go to a tex file rather than (or in addition to) directly using the output in the .Rmd file, we can make the following tweak:

custom_table <- function(dataset_labels, ..., cat_output=TRUE, out_file=NULL) {
tbl <- capture.output(stargazer::stargazer(...))
pattern1 <- 'Dependent variable:'
pattern2 <- '(?<= \\& ).+(?= \\\\)'
first_row_index <- which(grepl(pattern=pattern1, x=tbl))
first_row <- tbl[first_row_index]
colspan <- as.numeric(gsub(pattern='[^0-9]+', replacement='', first_row))
colspan <- colspan / length(dataset_labels)
new_first_row <- sub('[0-9]+', colspan, first_row)
replacement <- rep(stringr::str_extract(new_first_row, pattern2), 2)
replacement <- stringr::str_replace(replacement, pattern1, dataset_labels)
replacement <- paste(replacement, collapse=' & ')
new_first_row <- stringr::str_replace(new_first_row, pattern2, replacement)
new_first_row <- stringr::str_replace_all(new_first_row, 'multi', '\\\\multi')
new_first_row <- stringr::str_replace_all(new_first_row, 'textit', '\\\\textit')
tbl[first_row_index] <- new_first_row
if ( cat_output ) {
cat(tbl, sep='\n')
}
if ( !is.null(out_file) ) {
cat(tbl, sep='\n', file=out_file)
}
}

Then if you run the code below in an R script, or put it in a chunk in an Rmd file, you will get the output written to the file 'test_out.tex' as well as directly output:

custom_table(c('Data: Swiss', 'Data: Swiss2'),
out_file='test_out.tex',
m1, m2, m3, m4, m5, m6, m7, m8,
type = "latex",
header=FALSE,
omit.stat=c("LL","ser","f","adj.rsq"),
font.size="tiny",
column.labels = c("(M1)", "(M2)", "(M3)", "(M4)", "(M5)", "(M6)", "(M7)", "(M8)"),
model.names = FALSE,
model.numbers = FALSE,
star.cutoffs = c(0.05, 0.01, 0.001),
dep.var.labels = c("Outcome 1", "Outcome 2", "Outcome 1", "Outcome 2"))

Using the out option of the stargazer() function won't quite work because stargazer() will write the output to out before we've had a chance to make our modifications to it, but this tweak works.



Related Topics



Leave a reply



Submit