Captions using R "tables" package with kableExtra formatting - r

I am trying to add a caption to a table output from the package "tables" in R followed by additional formatting using kableExtra.
Although other threads have found ways to add caption headers by using additional LaTeX code (Caption not appearing for LaTeX table when knitting using Hmisc LaTeX Function and Hmisc::latex not printing caption w/ tabular object), these solutions do not appear compatible with the more recent toKable() function which allows additional formatting with kableExtra.
Typically a caption would be added during when kable(x, caption = "mycaption") is used. However when it is genereated as following, an error will occur (Error in toKable(., booktabs = T) : 'table' must be a 'tabular' object.). It appears if I try to add any additional formatting through latex(), such as adding a caption, the object type will change making it unusable with the toKable() function. Any insight into how to use toKable() with additional LaTeX formatting that has been passed through latex() would be greatly appreciated!
library(tables)
library(magrittr)
library(kableExtra)
tabular((Species + 1) ~ (n=1) + Format(digits=2)* (Sepal.Length + Sepal.Width)*(mean + sd), data=iris) %>%
latex(., options = list(tabular = "longtable",
toprule = "\\caption{Table 1. My favorite caption}\\\\\\toprule")) %>%
toKable(., booktabs = T)
The LaTeX output before being passed to toKable():
\begin{longtable}{lccccc}
\caption{Table 1. My favorite caption}\\\toprule
& & \multicolumn{2}{c}{Sepal.Length} & \multicolumn{2}{c}{Sepal.Width} \\
Species & n & mean & sd & mean & \multicolumn{1}{c}{sd} \\
\hline
setosa & $\phantom{0}50$ & $5.01$ & $0.35$ & $3.43$ & $0.38$ \\
versicolor & $\phantom{0}50$ & $5.94$ & $0.52$ & $2.77$ & $0.31$ \\
virginica & $\phantom{0}50$ & $6.59$ & $0.64$ & $2.97$ & $0.32$ \\
All & $150$ & $5.84$ & $0.83$ & $3.06$ & $0.44$ \\
\hline
\end{longtable}

After tinkering around a bit with the code and trying to understand how each works... I tried pasting the options list directly into toKable. This seemed to work and it appears toKable shared similar options to those of latex().
tabular((Species + 1) ~ (n=1) + Format(digits=2)* (Sepal.Length + Sepal.Width)*(mean + sd),
data=iris) %>%
toKable(., booktabs = T,
options = list(tabular = "longtable",
toprule = "\\caption{My favorite caption}\\\\\\toprule"))
This spits out the following LaTex code correctly, as desired above:
\begin{longtable}{lccccc}
\caption{Table 1. My favorite caption}\\\toprule
& & \multicolumn{2}{c}{Sepal.Length} & \multicolumn{2}{c}{Sepal.Width} \\ \cmidrule(lr){3-4}\cmidrule(lr){5-6}
Species & n & mean & sd & mean & \multicolumn{1}{c}{sd} \\
\midrule
setosa & $\phantom{0}50$ & $5.01$ & $0.35$ & $3.43$ & $0.38$ \\
versicolor & $\phantom{0}50$ & $5.94$ & $0.52$ & $2.77$ & $0.31$ \\
virginica & $\phantom{0}50$ & $6.59$ & $0.64$ & $2.97$ & $0.32$ \\
All & $150$ & $5.84$ & $0.83$ & $3.06$ & $0.44$ \\
\bottomrule
\end{longtable}
The LaTeX code can then be presented as needed in reports or otherwise. In a Rmarkdown document converted to PDF this can look like (remember to call the tables andkableExtra packages):

Thank you for sharing, I was looking for exactly this. I can add the caption as above but it still appears just as normal body text and without a table reference when I render the Latex doc. SO in case useful for anyone else
What worked for me was to use the latexTable function from the vignette:
tab1<-latexTable(tabular((Species + 1) ~ (n=1) + Format(digits=2)
(Sepal.Length + Sepal.Width)*(mean + sd),data=iris), caption = "Iris sepal data", label = "sepals")
and then and just treated it as a kable object and could add headers, etc
tab1 %>% add_header_above(c("Blah" = 1, "Bing" = 2, "Bong" = 2)) %>% save_kable(paste0(resultspath,"tab1.tex"), float = FALSE)

Related

(R, xtable package) sanitize.text.function is not working

I want to include a data table from R in a LaTeX file. I am using xtableand the problem is that the function sanitize.text.function is not working properly. MWE:
> a <- matrix(c("name & surname", 12345), ncol = 2)
[,1] [,2]
[1,] "name & surname" "12345"
> print.xtable(xtable(a), type = "latex", sanitize.text.function = function(x){x}, file = "../R_out/prova.tex")
\begin{table}[ht]
\centering
\begin{tabular}{rll}
\hline
& 1 & 2 \\
\hline
1 & name & surname & 12345 \\
\hline
\end{tabular}
\end{table}
As you can see there is a & in excess.
The only other similar question that I could find on stackoverflow concerned the location of the option sanitize.text.function, but in my case it should be correctly placed. Can you see the problem here?

R: math notation in data.frame

> df = data.frame(Parameters = c(expression(beta[1])))
Error in as.data.frame.default(x[[i]], optional = TRUE) :
cannot coerce class ""expression"" to a data.frame
I'm trying to write math notation in a data.frame, but it seems that the two are not compatible. Is there a way around this?
I have also tried
> data.frame(Parameters = paste(expression(beta[1])))
Parameters
1 beta[1]
How can I get to show up?
If you want to store the latex code for those symbols inside a dataframe then be able to generate correct latex code from xtable, you will need to override the sanitize function in print.xtable by feeding in a dummy function that returns the input exactly (See this question: Using xtable with R and Latex, math mode in column names?):
df = data.frame(Parameter = c("$\\beta_{0}$", "$\\beta_{1}$", "$\\beta_{2}$"),
Estimate = beta, row.names = 1)
print(xtable(t(df)), sanitize.text.function = function(x){x})
Latex Table:
\begin{table}[ht]
\centering
\begin{tabular}{rrrr}
\hline
& $\beta_{0}$ & $\beta_{1}$ & $\beta_{2}$ \\
\hline
Estimate & 0.05 & 0.10 & 0.15 \\
\hline
\end{tabular}
\end{table}
Similar to xtable, stargazer has some cool options to generate nice looking tables in latex. One thing you can do is to change the variable names to math notation using the covariate.labels argument in stargazer:
library(stargazer)
beta = 1:3*0.05
df = data.frame(Parameter = c("beta0", "beta1", "beta2"),
Estimate = beta, row.names = 1)
stargazer(t(df), covariate.labels = c(NA, "$\\beta_{0}$", "$\\beta_{1}$", "$\\beta_{2}$"),
header = FALSE, summary = FALSE)
This outputs a latex table code:
\begin{table}[!htbp] \centering
\caption{}
\label{}
\begin{tabular}{#{\extracolsep{5pt}} cccc}
\\[-1.8ex]\hline
\hline \\[-1.8ex]
& $\beta_{0}$ & $\beta_{1}$ & $\beta_{2}$ \\
\hline \\[-1.8ex]
Estimate & $0.050$ & $0.100$ & $0.150$ \\
\hline \\[-1.8ex]
\end{tabular}
\end{table}
You can copy and paste the code here to render the latex table.
Also note that the default for type= in stargazer is "latex", which generates latex code, but you can also specify type="text" to generate a table in your console. This option, however, does not allow you to render the math symbols.
stargazer(t(df), covariate.labels = c(NA, "$\\beta_{0}$", "$\\beta_{1}$", "$\\beta_{2}$"),
header = FALSE, summary = FALSE, type = "text")
# ==========================
# 0 1 2
# --------------------------
# Estimate 0.050 0.100 0.150
# --------------------------
Another option using my package:
library(huxtable)
dfr = data.frame(Parameter = c("$\\beta_{0}$", "$\\beta_{1}$", "$\\beta_{2}$"),
Estimate = 'beta')
ht <- as_hux(dfr)
escape_contents(ht) <- FALSE
ht # will print as TeX within a markdown pdf_document
I am not very sure what you are trying to do here. If you are trying to create a dataframe df with a column named "Parameter" with values taken from a vector within a list beta, then the below code will do the job.
df = data.frame(Parameters = beta[[1]])
# Assuming that the first object in beta is a vector that you want to set as "Paramters" column.
Please provide more information as to what these objects are if this is not what you were looking for.

Right-align LaTeX longtables through R's print.xtable

Say I have the following program in R to generate a LaTeX longtable:
library(xtable)
tabela <- xtabs(Temp ~ Month, airquality)
xtabela <- xtable(tabela)
print.xtable(xtabela, tabular.environment = 'longtable', floating = FALSE)
Which yields
\begin{longtable}{rr}
\hline
& Month \\
\hline
5 & 2032.00 \\
6 & 2373.00 \\
7 & 2601.00 \\
8 & 2603.00 \\
9 & 2307.00 \\
\hline
\hline
\end{longtable}
However, I want this table to be completely aligned to the right. In LaTeX, I just need to use \begin{longtable}[r]{rr} in order to accomplish this, but how do I pass this [r] argument through R's print.xtable? Alternatively, how do I achieve the same result through other methods (I've tried \raggedleft, but it only works with regular tabular objects)?
As a very rough method, you could do:
cat(paste(c("\\begin{longtable}[r]{", align(xt), "}\n"), collapse=""))
print(xtabella, only.contents=T)
cat("\\end{longtable}\n")

Displaying degrees of freedom in stargazer table

When constructing documents with Sweave and R, I make use of the stargazer library for tables.
When using stargazer, is there a mechanism to display the degrees of freedom associated with the residual deviance for a model constructed with glm?
Minimal code:
library(stargazer)
set.seed(1234)
data <- data.frame(x=1:10)
data$y <- data$x + rnorm(10, 0, 0.2)
model <- glm(y~x, data=data, family=gaussian)
summary(model)
stargazer(model,title="A test", align=T,label="Tab:test",style="all2")
Resultant stargazer table will have Observations, Log Likelihood, AIC, Residual Deviance and Null Deviance but no d.f. I can work out d.f. but would have thought this could be displayed directly. Also see:
https://sites.google.com/site/marekhlavac/stargazer
Update #1:
Thank you Marek for your response. For the benefit of others that encounter this, here is the process that lets you form the work around:
Obtain version 4.0 (not 4.5 - I'll come back to this) from http://cran.r-project.org/src/contrib/Archive/stargazer/
Within the package directory structure under R, edit "stargazer-internal.R" as per the instructions in the answer below.
Ensure that the library is not loaded in your R session
Ensure that you have removed any existing stargazer lib
Install the edited version of the stargazer package.
Reload the library in R and compile as per usual.
Here are the commands:
detach("package:stargazer", unload=TRUE)
remove.packages("stargazer")
From the command line:
R CMD INSTALL -l <path to library directory> stargazer
Finally (assuming you have a few models at hand),
library(stargazer)
stargazer(model6,model7,model8, title="Logistic model summary",align=T,label="Tab:logmod1", font.size="footnotesize", style="all2")
Result:
% Table created by stargazer v.4.0 by Marek Hlavac, Harvard University. E-mail: hlavac at fas.harvard.edu
% Date and time: Tue, Sep 24, 2013 - 17:17:17
% Requires LaTeX packages: dcolumn
\begin{table}[!htbp] \centering
\caption{Logistic model summary}
\label{Tab:logmod1}
\footnotesize
\begin{tabular}{#{\extracolsep{5pt}}lD{.}{.}{-3} D{.}{.}{-3} D{.}{.}{-3} }
\\[-1.8ex]\hline
\hline \\[-1.8ex]
& \multicolumn{3}{c}{\textit{Dependent variable:}} \\
\cline{2-4}
\\[-1.8ex] & \multicolumn{3}{c}{whalesighted} \\
\\[-1.8ex] & \multicolumn{1}{c}{\textit{logistic}} & \multicolumn{1}{c}{\textit{probit}} & \multicolumn{1}{c}{\textit{glm: binomial}} \\
& \multicolumn{1}{c}{\textit{}} & \multicolumn{1}{c}{\textit{}} & \multicolumn{1}{c}{\textit{link = cloglog}} \\
\\[-1.8ex] & \multicolumn{1}{c}{(1)} & \multicolumn{1}{c}{(2)} & \multicolumn{1}{c}{(3)}\\
\hline \\[-1.8ex]
visibility & 0.392^{***} & 0.226^{***} & 0.216^{***} \\
& (0.051) & (0.027) & (0.026) \\
Constant & -1.251^{***} & -0.745^{***} & -1.149^{***} \\
& (0.246) & (0.144) & (0.182) \\
\hline \\[-1.8ex]
Observations & \multicolumn{1}{c}{232} & \multicolumn{1}{c}{232} & \multicolumn{1}{c}{232} \\
Log Likelihood & \multicolumn{1}{c}{-110.485} & \multicolumn{1}{c}{-110.888} & \multicolumn{1}{c}{-112.694} \\
Akaike Inf. Crit. & \multicolumn{1}{c}{224.970} & \multicolumn{1}{c}{225.775} & \multicolumn{1}{c}{229.388} \\
Residual Deviance (df = 230) & \multicolumn{1}{c}{220.970} & \multicolumn{1}{c}{221.775} & \multicolumn{1}{c}{225.388} \\
Null Deviance (df = 231) & \multicolumn{1}{c}{310.759} & \multicolumn{1}{c}{310.759} & \multicolumn{1}{c}{310.759} \\
\hline
\hline \\[-1.8ex]
\textit{Note:} & \multicolumn{3}{r}{$^{*}$p$<$0.1; $^{**}$p$<$0.05; $^{***}$p$<$0.01} \\
\normalsize
\end{tabular}
\end{table}
Returning to the error I get when I implement the workaround based on the 4.5 code. I actually get the same error when I install from the mac binary (version 4.5.1) (http://cran.r-project.org/web/packages/stargazer/index.html) and simply try to use stargazer, see below.
> install.packages("stargazer")
trying URL 'http://cran.ms.unimelb.edu.au/bin/macosx/contrib/3.0/stargazer_4.5.1.tgz'
Content type 'application/x-tar' length 332917 bytes (325 Kb)
opened URL
==================================================
downloaded 325 Kb
> stargazer(model6,model7,model8,
+ title="Logistic model summary",
+ align=T,
+ label="Tab:logmod1",
+ font.size="footnotesize",
+ style="all2")
Error in `rownames<-`(`*tmp*`, value = "visibility") :
length of 'dimnames' [1] not equal to array extent
Marek, for your reference I will email the results traceback() to you.
Cheers.
Stargazer author here. It looks like the package's default is not to output degrees of freedom for residual and null deviance. I will consider changing the default in a future release.
As a quick fix for now, you might wish to use the source package (from CRAN), and modify the function .adjust.settings.style in stargazer-internal.R to contain the following:
if (style == "all") {
.format.table.parts <<- c("=!","dependent variable label","dependent variables","models","columns","numbers","-","coefficients","-","omit","-","additional","N","R-squared","adjusted R-squared","max R-squared","log likelihood","sigma2","theta(se)*(p)", "SER(df)","F statistic(df)*(p)","chi2(df)*(p)","Wald(df)*(p)","LR(df)*(p)","logrank(df)*(p)","AIC","BIC","UBRE","rho(se)*(p)","Mills(se)*(p)","residual deviance(df)*","null deviance(df)*","=!","notes")
.format.coefficient.table.parts <<- c("variable name","coefficient*","standard error","t-stat","p-value")
}
else if (style == "all2") {
.format.table.parts <<- c("=!","dependent variable label","dependent variables","models","columns","numbers","-","coefficients","-","omit","-","additional","N","R-squared","adjusted R-squared","max R-squared","log likelihood","sigma2","theta(se)*(p)", "SER(df)","F statistic(df)*(p)","chi2(df)*(p)","Wald(df)*(p)","LR(df)*(p)","logrank(df)*(p)","AIC","BIC","UBRE","rho(se)*(p)","Mills(se)*(p)","residual deviance(df)*","null deviance(df)*","=!","notes")
.format.coefficient.table.parts <<- c("variable name","coefficient*","standard error")
}
Note that the only change here is that I added "(df)*" to "residual deviance" and "null deviance".

Stargazer and gam - how to include the whole summary output?

When fitting a generalized additive model with smoothed splines stargazer only returns the main effects and not the smooth terms which you can see in summary(pros.gam). Can stargazer return these as well? Or is there another function or package that can do the job?
library(ElemStatLearn)
library(mgcv)
library(stargazer)
pros.gam=gam(lpsa~s(lcavol)+s(lweight)+s(age)+s(lbph)+svi
+s(lcp)+gleason+s(pgg45),data=prostate)
summary(pros.gam) # Table should include the smooth terms that are visible here
stargazer(pros.gam,summary=TRUE)
toLatex of the utils package does the job:
require(utils)
toLatex(summary(pros.gam)$s.table)
Output:
# \begin{tabular}{lD{.}{.}{7}D{.}{.}{7}D{.}{.}{7}D{.}{.}{7}}
# \toprule
# & \multicolumn{1}{c}{edf} & \multicolumn{1}{c}{Ref.df} & \multicolumn{1}{c}{F} & \multicolumn{1}{c}{p-value} \\
# \midrule
# s(lcavol) & 1.0000000 & 1.0000000 & 48.8654347 & 0.0000000 \\
# s(lweight) & 7.4334733 & 8.3759397 & 2.9521585 & 0.0054553 \\
# s(age) & 1.7609527 & 2.1888342 & 3.2466098 & 0.0402275 \\
# s(lbph) & 1.7480193 & 2.1293872 & 2.3329425 & 0.0998080 \\
# s(lcp) & 3.3087460 & 4.0189658 & 1.3792509 & 0.2484695 \\
# s(pgg45) & 1.1277962 & 1.2388741 & 0.2681440 & 0.6563885 \\
# \bottomrule
# \end{tabular}
I was having the same problem converting the output of GAM models (mgcv package), I got what I wanted with the "itsadug" package authored by R. Harald Baayen.
Convert model summary into Latex / HTML table for knitr / R Markdown reports.
data(simdat)
Model with random effect and interactions:
m1 <- bam(Y ~ Group+te(Time, Trial, by=Group),data=simdat)
summary(m1)
gamtabs(m1, caption='Summary of m1')
See for more examples:
vignette("inspect", package="itsadug")

Resources