Why is LaTeX failing to compile in RMarkdown - r

My code should be a pretty easy knit to a pdf, but it will not compile and I'm getting this message in R Markdown:
! LaTeX Error: Unicode character ₁ (U+2081)
not set up for use with LaTeX.
Error: LaTeX failed to compile L-work-5.tex. See https://yihui.org/tinytex/r/#debugging for debugging tips. See L- work-5.log for more info.
Execution halted
here is the code:
---
title: "work 5"
author: "PLars"
date: "4/2/2022"
output: pdf_document
fonttheme: professionalfonts
fontsize: 12pt
editor_options:
markdown:
wrap: 72
---
```{r, echo = FALSE, results = "hide", message = FALSE, purl = FALSE}
library(knitr)
opts_chunk$set(tidy = FALSE,
fig.align = "left",
background = '#a6a6a6',
fig.width = 10,
fig.height = 10,
out.width ="\\linewidth",
out.height = "\\linewidth",
message = FALSE,
warning = FALSE,
fig.align = "left"
)
options(width = 55, digits = 3)
library(scales)
percent <- function(x, digits = 2, format = "f", ...) {
paste0(formatC(100 * x, format = format, digits = digits, ...), "%")
}
library(haven)
library(tinytex)
library(stargazer)
library(tidyverse)
library(texreg)
library(dplyr)
library(texreg)
library(AER)
library(tidyverse)
```
**Part I - Categorical Models (5 points)**
Say that you estimate an ordered logit model with a three category
dependent variable and two independent variables, X~₁i~ and X~₂i~, and
obtain the following results:
```{=tex}
\begin{center}
\begin{tabular}{c|rc}
\hline \hline
& $\hat{\beta}$ & SE \\
\hline
$X_{1}$ & $-0.68$ & $(0.23)$ \\
$X_{2}$ & $-0.47$ & $(0.13)$ \\
\hline
$\tau_1$ & $-1.02$ & $(0.46)$ \\
$\tau_2$ & $.85$ & $(0.21)$ \\
\hline
\end{tabular}
\end{center}
```
```{=tex}
\begin{enumerate}
\item Calculate $\Pr(Y_i=1 | X_{1i}=1, X_{2i}=0)$.
\item Calculate $\Pr(Y_i=2 | X_{1i}=1, X_{2i}=0)$.
\item Calculate $\Pr(Y_i=3 | X_{1i}=1, X_{2i}=0)$.
\item Calculate the first difference (difference in probability in category) that result from changing X_{2i} from -2 to 2, holding X_{1i} fixed at 0. Do calculations for each possible value of Y_i.
\item Explain how we might assess whether the parallel regression assumption holds for this model? If it does not, what alternative might you pursue if this were your model?
\end{enumerate}
```
#
First, we calculate $X_i \beta$
```{r}
(xiB <- (-.068*1) + (-0.47*0))
```
Then, plug into the following equations:
```{r}
(prob1 <- 1/(1 + exp(-(-1.02-xiB))))
(prob2 <- 1/(1 + exp(-(.85-xiB))) - prob1)
(prob3 <- 1 - (1/(1 + exp(-(.85-xiB)))))
prob1 + prob2 + prob3
```

For a start, try deleting the special characters ₁ and ₂ in the line
two independent variables, X~₁i~ and X~₂i~
This will let you compile.
You might be able to get this to work by including something like
\newunicodechar{₁}{\ensuremath{{}_1}}
and similarly for the subscript-2 character, at the top of your file (from this TeX Stack Exchange question), but I haven't tested it and don't want to go down that rabbit hole right now ...
Or just change the relevant text to
two independent variables, $X_{1i}$ and $X_{2i}$
which will probably typeset it as originally intended!

Related

Return both text and inline r markdown from within a function

Uses:
install.packages("bookdown")
library(bookdown)
GitHub: https://github.com/MartinJLambert/r-markdown_function_test
Given that I need to reproduce these values multiple times within the same document, I have created a function that calculates a simple ANOVA and determines the F, df, p and n statistics, as well as an asterix indicator for significance based on the p-value.
---
output:
bookdown::pdf_document2
---
```{r include= FALSE}
# function for calculating and displaying statistics results from an ANOVA
func_aov_stats <- function(input_df, input_var, input_factor) {
aov_tmp <- aov(input_var ~ input_factor, input_df)
anova_tmp <- anova(aov_tmp)
temp_signif <- if(anova_tmp[1,5] < 0.001){print("***")}
else if(anova_tmp[1,5] < 0.01){print("**")}
else if(anova_tmp[1,5] <0.05){print("*")}
else {print("")}
paste(anova_tmp[1,1], anova_tmp[1,4], anova_tmp[1,5], temp_signif, anova_tmp[2,1]+2)
}
```
`r func_aov_stats(mtcars, mtcars$mpg, mtcars$cyl)`
This is simple enough and knitting this does exactly what I want it to do.
1 79.5610275293349 6.11268714258098e-10 *** 32
However, numbers alone are kinda useless, so I would like to report it as a string of text. Something along these lines:
ANOVA: F(df=anova_tmp[1,1]) = anova_tmp[1,4], p
= anova_tmp[1,5] temp_signif, n = anova_tmp[2,1]+2
I was thinking of simply pasting the inline r-markdown inside the function:
paste("ANOVA: F~(df=`r anova_tmp[1,1]`)~ = `r anova_tmp[1,4]`, p = `r paste(anova_tmp[1,5] temp_signif)`, n = `r anova_tmp[2,1]+2`")
But I get this:
ANOVA: F(df=r anova_tmp[1,1]) = r anova_tmp[1,4], p = r anova_tmp[1,5] temp_signif, n = r anova_tmp[2,1]+2
At least the markdown formatting worked, but it obviously doesn't paste the 'r' components as hoped.
What does work, is if I write it out manually outside of the function, elsewhere in the markdown document:
```{r outside_of_function, include= FALSE}
aov_tmp <- aov(mpg ~ cyl, mtcars)
anova_tmp <- anova(aov_tmp)
temp_signif <- if(anova_tmp[1,5] < 0.001){print("***")} else if(anova_tmp[1,5] < 0.01){print("**")} else if(anova_tmp[1,5] <0.05){print("*")} else {print("")}
```
ANOVA: F~(df=`r anova_tmp[1,1]`)~ = `r anova_tmp[1,4]`, p = `r paste(anova_tmp[1,5], temp_signif)`, n = `r anova_tmp[2,1]+2`
ANOVA: F(df=1) = 79.5610275, p = 6.11268714258098e-10 ***, n = 32
So the issue is within the function itself. While it does seem to be able to produce the formatting, the computation of the 'r' code seems to require something beyond my understanding.
The solution is: paste0().
Full code, updated and fully functioning:
---
output:
bookdown::pdf_document2
---
```{r include = FALSE}
# function for calculating and displaying statistics results from an ANOVA
func_aov_stats <- function(input_df, input_var, input_factor) {
aov_tmp <- aov(input_var ~ input_factor, input_df)
anova_tmp <- anova(aov_tmp)
temp_signif <- if(anova_tmp[1,5] < 0.001){print("***")}
else if(anova_tmp[1,5] < 0.01){print("**")}
else if(anova_tmp[1,5] <0.05){print("*")}
else {print("")}
paste0("ANOVA: F~(df=",anova_tmp[1,1],")~= ",anova_tmp[1,4],", p = ",anova_tmp[1,5]," ",temp_signif," n = ",anova_tmp[2,1]+2)
}
```
`r func_aov_stats(mtcars, mtcars$mpg, mtcars$cyl)`

Using R Hmisc summary/summaryM latex command within Knitr Markdown pdf

I have been trying to get the Hmisc latex.summary and latex.summaryM examples to work within a pdf document created using Knitr in RStudio. But keep getting error messages. The example data is:
options(digits=3)
set.seed(173)
sex <- factor(sample(c("m","f"), 500, rep=TRUE))
country <- factor(sample(c('US', 'Canada'), 500, rep=TRUE))
age <- rnorm(500, 50, 5)
sbp <- rnorm(500, 120, 12)
label(sbp) <- 'Systolic BP'
units(sbp) <- "mmHg"
treatment <- factor(sample(c("Drug","Placebo"), 500, rep=TRUE))
sbp[1] <- NA
# Generate a 3-choice variable; each of 3 variables has 5 possible levels
symp <- c('Headache','Stomach Ache','Hangnail',
'Muscle Ache','Depressed')
symptom1 <- sample(symp, 500,TRUE)
symptom2 <- sample(symp, 500,TRUE)
symptom3 <- sample(symp, 500,TRUE)
Symptoms <- mChoice(symptom1, symptom2, symptom3, label='Primary Symptoms')
And I want to create a pdf document that contains the tables
tab1 <- summary(sex ~ treatment + Symptoms, fun=table)
tab2 <- summaryM(age + sex + sbp + Symptoms ~ treatment,
groups='treatment', test=TRUE)
I'm running R version 3.5.2 (2018-12-20), RStudio 1.1.463, Hmisc_4.2-0, and have installed tinytex using tinytex::install_tinytex().
After a few hours trial and error I discovered how, and am posting the code below in case it helps others.
The following code works for me, note;
Requirement for relsize latex package when Hmisc::units attribute is used to prevent the following failed to compile error.
! Undefined control sequence.
<recently read> \smaller
The mylatex function is taken from https://stackoverflow.com/a/31443576/4241780, and is required for removing unwanted output.
The option file = "" is needed to prevent the error
Error in system(comd, intern = TRUE, wait = TRUE) : 'yap' not found
Calls: <Anonymous> ... print -> print.latex -> show.latex -> show.dvi -> system
The use of the where = "!htbp" option ensures that the tables remain where they are placed and do not float to the top of the page (by default where = "!tbp") https://tex.stackexchange.com/a/2282.
---
title: "Untitled"
author: "Author"
date: "15 April 2019"
output:
pdf_document:
extra_dependencies: ["relsize"]
---
```{r setup, include=FALSE}
library(Hmisc)
library(dplyr)
mylatex <- function (...) {
o <- capture.output(latex(file = "", where = "!htbp", ...))
# this will strip /all/ line-only comments; or if you're only
# interested in stripping the first such comment you could
# adjust accordingly
o <- grep('^%', o, inv=T, value=T)
cat(o, sep='\n')
}
```
```{r data}
# As in question above ...
```
Here is the first table
```{r tab1, results = "asis"}
tab1 <- summary(sex ~ treatment + Symptoms, fun=table)
mylatex(tab1)
```
Here is the second table
```{r tab2, results = "asis"}
tab2 <- summaryM(age + sex + sbp + Symptoms ~ treatment, test=TRUE)
mylatex(tab2)
```

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.

xtable inside of a for loop in Rmarkdown is printing {} in output when floating = FALSE [duplicate]

I'm creating a R Markdown document using knitr and am running into trouble using xtable to create a table. My table is very large and I'm trying to reduce the size using the size command in the print statement. The issue I'm running into is that the command seems to add two extra curly braces which show up in the PDF, one before the table and one after.
Does anyone know a way to fix this?
MWE:
---
output:
pdf_document:
keep_tex: yes
tables: true
---
```{r, results='asis', echo=FALSE}
library(xtable)
my.df <- data.frame(matrix(c(1:18),nrow=2))
glossaryprint <- xtable(my.df, caption="Summary of Terms")
print(glossaryprint,
comment=FALSE,
floating=FALSE,
size="footnotesize"
)
```
Note: The issue that is subject of the question and this answer has been resolved in xtable 1.8-2.
Although the question has been self-answered with a workaround, I think for other users some more details might be helpful.
What happens?
To understand what is happening here, we need to take a close look at the conversion steps the document undergoes on its way from RMD to PDF. The steps are:
RMD --> MD --> TEX --> PDF
Let's look at the files in reversed order:
PDF: (generated from TEX by pdflatex)
TEX: (generated from MD by pandoc)
% …
\{\footnotesize
\begin{tabular}{rrrr}
\hline
& X1 & X2 & X3 \\
\hline
1 & 1 & 3 & 5 \\
2 & 2 & 4 & 6 \\
\hline
\end{tabular}
\}
% …
MD (generated from RMD by knitr)
---
output:
pdf_document:
keep_tex: yes
---
{\footnotesize
\begin{tabular}{rrrr}
\hline
& X1 & X2 & X3 \\
\hline
1 & 1 & 3 & 5 \\
2 & 2 & 4 & 6 \\
\hline
\end{tabular}
}
RMD: (source file)
---
output:
pdf_document:
keep_tex: yes
---
```{r, results='asis', echo=FALSE}
library(xtable)
mytable <- xtable(data.frame(matrix(c(1:6), nrow = 2)))
print(mytable,
comment = FALSE,
floating = FALSE,
size = "footnotesize"
)
```
Recall: The problem is, that there are visible curly braces in the PDF. Where do they come from?
They are the result of the escaped curly braces in the TEX file (\{ and \}).
These curly braces also exist in the MD file, but there they are not escaped.
So we know two things by now: We see the curly braces because they are escaped and they are escaped by pandoc.
But why do these curly braces exist at all? print.xtable outputs them when a size is specified. The goal is to create a group and to apply size only within that group. (With floating = TRUE, no grouping by curly braces is required because there is a figure environment whithin which the size is set. The curly braces are printed anyways.)
And why does pandoc escape that pair of curly braces but leaves all the other curly braces (e.g. in \begin{tabular}) unescaped? This is because pandoc is supposed to escape special characters that are meant literally but leave raw LaTeX unescaped. However, pandoc does not know that the outer curly braces are LaTeX commands and not text.
(With floating = TRUE the problem does not occur because the curly braces are within a figure environment which is recognized as LaTeX.)
Solutions
After having understood the problem, what can we do about it? One solution has already been posted by the OP: Abstain from spefifying size in print.xtable and insert the footnotesize command manually:
---
output:
pdf_document:
keep_tex: yes
---
```{r, results='asis', echo=FALSE}
library(xtable)
mytable <- xtable(data.frame(matrix(c(1:6), nrow = 2)))
cat("\\begin{footnotesize}")
print(mytable,
comment = FALSE,
floating = FALSE
)
cat("\\end{footnotesize}")
```
However, on the long run it would be nice if xtable (current version: 1.8-0) generated LaTeX code that survives the pandoc conversion. This is quite simple: print.xtable checks if size is set and if so, inserts { before the size specification and } at the end of the table:
if (is.null(size) || !is.character(size)) {
BSIZE <- ""
ESIZE <- ""
}
else {
if (length(grep("^\\\\", size)) == 0) {
size <- paste("\\", size, sep = "")
}
BSIZE <- paste("{", size, "\n", sep = "")
ESIZE <- "}\n"
}
This small modification replaces { with \begingroup and } with \endgroup:
if (is.null(size) || !is.character(size)) {
BSIZE <- ""
ESIZE <- ""
}
else {
if (length(grep("^\\\\", size)) == 0) {
size <- paste("\\", size, sep = "")
}
BSIZE <- paste("\\begingroup", size, "\n", sep = "")
ESIZE <- "\\endgroup\n"
}
For LaTeX, this makes no difference, but as pandoc recognizes \begingroup (as oppsed to {) it should solve the problem. I reported this as a bug in xtable and hopefully the issue will be fixed in future versions.
I was able to fix this by not including the size parameter in the print statement but rather directly before and after the chunk.
\begin{footnotesize}
#chunk
\end{footnotesize}

Combine texreg, knitr, booktabs & dcolumn

I'm trying to compile a LaTeX report using RStudio and knitr. I'm having a hard time getting the packages booktabs and dcolumn to work with my texreg-generated table.
As an example, I am trying to recreate Table 2 in this example:.
My attempt as a .Rnw -file is below:
\documentclass{article}
\usepackage{booktabs}
\usepackage{dcolumn}
<<setup, include=FALSE >>=
library(texreg)
#
\begin{document}
<<analysis, include=FALSE>>=
ctl <- c(4.17,5.58,5.18,6.11,4.50,4.61,5.17,4.53,5.33,5.14)
trt <- c(4.81,4.17,4.41,3.59,5.87,3.83,6.03,4.89,4.32,4.69)
group <- gl(2,10,20, labels=c("Ctl","Trt"))
weight <- c(ctl, trt)
m1 <- lm(weight ~ group)
m2 <- lm(weight ~ group - 1) # omitting intercept
#
<<table, results='asis'>>=
texreg(m2)
#
\end{document}
However, the generated LaTex table (below) includes neither the booktabs horizontal lines nor the dcolumn alignment. How to incorporate them? Many thanks for help!
\begin{table}
\begin{center}
\begin{tabular}{l c }
\hline
& Model 1 \\
\hline
groupCtl & $5.03^{***}$ \\
& $(0.22)$ \\
groupTrt & $4.66^{***}$ \\
& $(0.22)$ \\
\hline
R$^2$ & 0.98 \\
Adj. R$^2$ & 0.98 \\
Num. obs. & 20 \\
\hline
\multicolumn{2}{l}{\scriptsize{$^{***}p<0.001$, $^{**}p<0.01$, $^*p<0.05$}}
\end{tabular}
\caption{Statistical models}
\label{table:coefficients}
\end{center}
\end{table}
Just to clarify: the crucial part in Robert's solution is the argument use.packages=FALSE not the seperation of code into two chunks.
The reason is the following: The way you call texreg() now makes it include the following in the tex output it produces:
\usepackage{booktabs}
\usepackage{dcolumn}
Saving the output in an object and then using cat() does not solve this.
You cannot use \usepackage()' outside the preamble. Knitr still compiles a PDF but apparently this use of\usepackage{}' in the document body screws up the use of booktabs and dcolumn even if you've loaded them in the preamble.
Add the argument use.packages=FALSE in texreg() - if set to FALSE, the use package statements are omitted from the output. Write the use package statements into the preamble of your document yourself and you'll have the regression table with booktabs and aligned numbers.
Try this:
\begin{document}
<<analysis, include=FALSE>>=
ctl <- c(4.17,5.58,5.18,6.11,4.50,4.61,5.17,4.53,5.33,5.14)
trt <- c(4.81,4.17,4.41,3.59,5.87,3.83,6.03,4.89,4.32,4.69)
group <- gl(2,10,20, labels=c("Ctl","Trt"))
weight <- c(ctl, trt)
m1 <- lm(weight ~ group)
m2 <- lm(weight ~ group - 1) # omitting intercept
table = texreg(m2,booktabs = TRUE,dcolumn = TRUE,use.packages=FALSE)
table2=texreg(list(m1,m2),booktabs = TRUE,dcolumn = TRUE,use.packages=FALSE)
#
<<table, results='asis',echo=FALSE>>=
cat(table)
cat(table2)
#
\end{document}

Resources