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

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?

Related

Captions using R "tables" package with kableExtra formatting

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)

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")

How do get Hmisc latex function to show only table contents

Running latex(rnorm(5),file="") through the Hmisc package will display both the contents of the table; for example:
$-0.8036409661674679$\tabularnewline
$ 1.2066652279406598$\tabularnewline
but it will also show the table preamble and ending; for example:
\end{center}
\end{table}
How do I force the command to only show the formatted contents of the table and not the table preamble/ending?
require(Hmisc)
latex(rnorm(5),file="")
You should see ?Hmisc::latex for arguments values. You can supress table and center environment without rewriting function:
> latex(rnorm(5),file="", table.env=FALSE, center="none", multicol=FALSE)
% latex.default(rnorm(5), file = "", table.env = FALSE, center = "none", multicol = FALSE)
%
\begin{tabular}{r}
\hline\hline
\tabularnewline
\hline
$ 0.170715837013809$\tabularnewline
$ 1.825384093014966$\tabularnewline
$-0.390987768400953$\tabularnewline
$ 1.429885144215387$\tabularnewline
$-0.505248111252067$\tabularnewline
\hline
\end{tabular}
Hmisc::format_df function will give you the desired result:
> x <- format.df(rnorm(5))
> cat(paste(x, "\\\\", collapse="\n"))
$ 0.184705304659614$ \\
$-1.570758868384333$ \\
$ 0.442248007654160$ \\
$-0.317095653252702$ \\
$ 0.160679032355016$ \\

How to remove "Standard Error" column from xtable() output of an lm on R/RSweave/LaTeX

I'm currently doing some data analysis on population data, so reporting the standard errors in the tables of parameter coefficients just doesn't really make statistical sense. I've done a fair bit of searching and can't find any way to customize the xtable output to remove it. Can anyone point me in the right direction?
Thanks a lot, I didn't post this lightly; if it's something obvious, I apologize for having wasted time!
so after my (other) whole long-winded answer... this works too:
xtable(summary(model1)$coefficients[,c(1,3,4)])
Or more generically:
sm <- summary(SomeModel)
SE.indx <- which(colnames(sm$coefficients) == "Std. Error") # find which column is Std. Error (usually 2nd)
sm$coefficients <- sm$coefficients[, -SE.indx] # Remove it
xtable(sm$coefficients) # call xtable on just the coefficients table
Results:
% latex table generated in R 2.15.1 by xtable 1.7-0 package
% Sun Dec 9 00:01:46 2012
\begin{table}[ht]
\begin{center}
\begin{tabular}{rrrr}
\hline
& Estimate & t value & Pr($>$$|$t$|$) \\
\hline
(Intercept) & 29.80 & 30.70 & 0.00 \\
crim & -0.31 & -6.91 & 0.00 \\
age & -0.09 & -6.50 & 0.00 \\
\hline
\end{tabular}
\end{center}
\end{table}
Using the first example in help(lm):
xtable(as.matrix(coef(lm.D9)))
% latex table generated in R 2.15.2 by xtable 1.7-0 package
% Sat Dec 8 19:53:09 2012
\begin{table}[ht]
\begin{center}
\begin{tabular}{rr}
\hline
& x \\
\hline
(Intercept) & 5.03 \\
groupTrt & -0.37 \\
\hline
\end{tabular}
\end{center}
\end{table}
I agreed with not using std erros if this were descriptions of a population and not just a sample. By that reasoning, however, you would not want to leave in p-values or t-statistics. That was the reason I only included the coefficients. To remove the standard error column only from the summary coefficient matrix:
xtable( coef(summary(lm.D9))[,-2] )
% latex table generated in R 2.15.2 by xtable 1.7-0 package
% Sat Dec 8 21:02:17 2012
\begin{table}[ht]
\begin{center}
\begin{tabular}{rrrr}
\hline
& Estimate & t value & Pr($>$$|$t$|$) \\
\hline
(Intercept) & 5.03 & 22.85 & 0.00 \\
groupTrt & -0.37 & -1.19 & 0.25 \\
\hline
\end{tabular}
\end{center}
\end{table}
Looking at str(summary(Model1)) we see that $coefficients has the Std. Error value we want to remove.
lesserSummary <- function(x) {
## returns same as summary(x), but with "Std. Error" remove from coefficients.
## and class of object is "modifiedSummary"
# grab the summary
sm <- summary(x)
# find which column is std error
SE.indx <- which(colnames(sm$coefficients) == "Std. Error")
# remove it
sm$coefficients <- sm$coefficients[, -SE.indx]
# give it some class
class(sm) <- "modifiedSummary"
# return it
sm
}
xtable.modifiedSummary <-
function (x, caption = NULL, label = NULL, align = NULL, digits = NULL, display = NULL, ...) {
# x is a modifiedSummary object
# This function is a modification of xtable:::xtable.summary.lm
# Key Difference is simply the number of columns that x$coef is expected to have
# (Here 3. Originally 4)
x <- data.frame(x$coef, check.names = FALSE)
class(x) <- c("xtable", "data.frame")
caption(x) <- caption
label(x) <- label
align(x) <- switch(1 + is.null(align), align, c("r", "r", "r", "r"))
digits(x) <- switch(1 + is.null(digits), digits, c(0, 4, 2, 4))
display(x) <- switch(1 + is.null(display), display, c("s", "f", "f", "f"))
return(x)
}
xtable_mod <- function(x) {
# Wrapper function to xtable.modified summary, calling first lesserSummary on x
xtable(lesserSummary(x))
}
EXAMPLE:
xtable_mod(model1)
% latex table generated in R 2.15.1 by xtable 1.7-0 package
% Sat Dec 8 23:44:54 2012
\begin{table}[ht]
\begin{center}
\begin{tabular}{rrrr}
\hline
& Estimate & t value & Pr($>$$|$t$|$) \\
\hline
(Intercept) & 29.8007 & 30.70 & 0.0000 \\
crim & -0.3118 & -6.91 & 0.0000 \\
age & -0.0896 & -6.50 & 0.0000 \\
\hline
\end{tabular}
\end{center}
\end{table}
Below are the steps taken to arrive at the above conclusion.
You can likely modify the call to xtable, but you first need to follow it down a bit:
start by looking at the source for xtable:
xtable
# function (x, caption = NULL, label = NULL, align = NULL, digits = NULL,
# display = NULL, ...)
# {
# UseMethod("xtable")
# }
# <environment: namespace:xtable>
We see that it simply has a call to UseMethod(). So lets see which methods are available:
methods(xtable)
# [1] xtable.anova* xtable.aov* xtable.aovlist*
# [4] xtable.coxph* xtable.data.frame* xtable.glm*
# [7] xtable.lm* xtable.matrix* xtable.prcomp*
# [10] xtable.summary.aov* xtable.summary.aovlist* xtable.summary.glm*
# [13] xtable.summary.lm* xtable.summary.prcomp* xtable.table*
# [16] xtable.ts* xtable.zoo*
There are several. Note that the ones with an asterisk * are non-visible.
The method called is determined by the class of the object we are calling xtable on.
Let's say our output is Model1 We take a look at its class: '
class(Model1)
# [1] "lm"
So the source we want to look at is xtable.lm.
xtable.lm
# Error: object 'xtable.lm' not found
Error? That's right, it is non-visible. So we use the package name with triple-colons. Note: please be sure to read the notice in the help file ?":::"
xtable:::xtable.lm
# function (x, caption = NULL, label = NULL, align = NULL, digits = NULL,
# display = NULL, ...)
# {
# return(xtable.summary.lm(summary(x), caption = caption, label = label,
# align = align, digits = digits, display = display))
# }
# <environment: namespace:xtable>
We notice that xtable.lm calls xtable.summary.lm and passes as its first argument a summary(x), where x is our model.
So that leads us to two place to investigate: summary and xtable.summary.lm

Resources