Reputation: 164
I want to automate the generation of descriptive tables with headings for groups of variables - using knitr and (ideally) stargazer. Since I need weighted descriptives, I do not use stargazer's built in summary functions but generate a dataframe containing the statistics and use the summary=FALSE
argument to print the dataframe.
Issue 1: A df with the variables and headings as rows and the summary statistics as columns does not work because stargazer transforms the NA
s on the heading rows into $$
s which breaks the knitting process.
Issue 2: As a work around, I generated a dataframe with variables and headings as columns and the summary statistics as rows and use the flip=TRUE
argument to have rows and columns flipped in the stargazer output. While this allows me to have empty character vectors for the headings and numeric vectors for the variables, stargazer does not output the numeric vectors in math mode but (appears to) treat them as character.
Example:
# create example df
df <- data.frame(heading=c(" "," "," "),var1=c(1,2,3),var2=c(4,5,6))
df$heading <- as.character(df$heading)
# output using stargazer
stargazer(df, summary = FALSE, flip = TRUE)
% Table created by stargazer v.5.2 by Marek Hlavac, Harvard University. E-mail: hlavac at fas.harvard.edu
% Date and time: Fri, Aug 12, 2016 - 10:39:01
\begin{table}[!htbp] \centering
\caption{}
\label{}
\begin{tabular}{@{\extracolsep{5pt}} cccc}
\\[-1.8ex]\hline
\hline \\[-1.8ex]
& 1 & 2 & 3 \\
\hline \\[-1.8ex]
heading & & & \\
var1 & 1 & 2 & 3 \\
var2 & 4 & 5 & 6 \\
\hline \\[-1.8ex]
\end{tabular}
\end{table}
Question: How do I add headings (empty rows) in the descriptive table and still get math mode output for the variable statistics?
Upvotes: 5
Views: 3980
Reputation: 14957
As mentioned by Konrad Rudolph, stargazer
probably cannot do this. The following solution uses xtable
instead:
\documentclass{article}
\usepackage{array}
\begin{document}
<<results = "asis", echo = FALSE>>=
library(xtable)
group1 <- data.frame(
name = c("v1", "v2"),
mean = 1:2, min = 3:4, max = 5:6,
stringsAsFactors = FALSE)
group2 <- data.frame(
name = c("v3", "v4"),
mean = -(1:2), min = -(3:4), max = -(5:6),
stringsAsFactors = FALSE)
dat <- rbind(
c("\\textbf{Group 1}", rep(NA, ncol(group1) - 1)),
group1,
c("\\textbf{Group 2}", rep(NA, ncol(group1) - 1)),
group2)
colnames(dat) <- sprintf("\\multicolumn{1}{c}{%s}", colnames(dat))
print.xtable(
xtable(dat,
caption = "Summary of Groups 1 and 2.",
align = c("l", "l", rep(">{$}r<{$}", 3))),
include.rownames = FALSE,
sanitize.text.function = identity,
sanitize.colnames.function = identity)
@
\end{document}
The concept is quite simple, but there are a few quirks to take into account:
rbind
ing the groups, simply insert rows for the headings, setting empty columns to NA
. Don't forget to double backslashes when using LaTeX in strings. (Use \multicolumn
if the headings are too wide.)align
argument of xtable
to specify the column type. We need one normal left-justified column and three right-justified columns in math mode. To force math mode, use >{$}r<{$}
, see here. (There's an additional l
which will be ignored – it is for the row names, which we hide.)sanitize.text.function
and sanitize.colnames.function
to identity
. Result:
Upvotes: 3