I'm actually creating a shiny app. In that app, there is a download button which download a PDF file that depends of user's input.
So I use a .rnw file to do generate that PDF document. I just want to do a table (with tabular) which have a number of row that depends of app user's input.
So in my R chunck, i'd like to do something like that :
\begin{tabular}{c|c}
<<echo=FALSE>>=
for (index in 1:nrow(myData))
{
SomethingThatRunLaTeXCode(paste0("\hline ",
"\Sexpr{",myData[index,1],"}"," % ","\Sexpr{",myData[index,2],"}"))
}
\hline
\end{tabular}
#
As suggested by sebastian-c, a much better way to make such a table is to use the xtable package together with Knitr. To make the Knitr chunks understand TeX, use the chunk option results='asis'.
Since your data is a data.frame, it is straight-forward:
<<echo = FALSE, results = "asis">>=
## test data
set.seed(1)
df <- data.frame(Gaussian = rnorm(10), Exponential = rexp(10))
library(xtable)
cap = paste("My caption can span multiple lines and",
"can be arbitrarily long.")
xtable(df,caption = cap)
#
For full customization, use the function print.xtable on your xtable object.
<<echo = FALSE, results = "asis">>=
print.xtable(xtable(df),table.placement = "")
#
Related
I have a data.frame that I need as a nice PDF table for a scientific poster. While it's very easy to export plots via pdf(), I'm stuck with this table.
I know how to get a PDF table with rmarkdown, e.g.
---
output: pdf_document
---
```{r tab, echo=FALSE, results='asis'}
library(xtable)
xtable(head(mtcars))
```
But I want this output directly from the R script, e.g.
renderThisToPDF(xtable(head(mtcars), to="nicetable.pdf") # fantasy code
How would I do this?
So far I attempted this code with a indirection via writeLines
code <- "library(xtable)\nprint(xtable(head(mtcars)))"
fileConn <- file("output.Rmd")
writeLines(cat("---\noutput: pdf_document\n---\n```{r tab, echo=FALSE, results='asis'}\n",
code, "\n```\n"), fileConn)
close(fileConn)
knitr::knit('output.Rmd')
but failed with an error.
Error in writeLines(cat("---\noutput: pdf_document\n---\n```{r tab, echo=FALSE,
results='asis'}\n", :
can only write character objects
I guess there's probably an easier solution?
Here is a possibility, without rmarkdown.
library(xtable)
latex <- print.xtable(xtable(head(iris)), print.results = FALSE)
writeLines(
c(
"\\documentclass[12pt]{article}",
"\\begin{document}",
"\\thispagestyle{empty}",
latex,
"\\end{document}"
),
"table.tex"
)
tools::texi2pdf("table.tex", clean = TRUE)
Or, using the standalone document class:
latex <- print.xtable(xtable(head(iris)), print.results = FALSE,
floating = FALSE)
writeLines(
c(
"\\documentclass[12pt]{standalone}",
"\\usepackage{caption}",
"\\begin{document}",
"\\minipage{\\textwidth}",
latex,
"\\captionof{table}{My caption}",
"\\endminipage",
"\\end{document}"
),
"table.tex"
)
tools::texi2pdf("table.tex", clean = TRUE)
One Solution would be to use tableGrob from gridExtra, add the table to a grid plot and save it with ggsave
require(ggplot2)
require(gridExtra)
ds <- iris[1:10, ]
tg <- tableGrob(ds)
ggsave("test.pdf", tg)
This is quite simple but will be less convinient than a LaTeX solution for more complex tables.
Here is a one-liner using the huxtable package (disclaimer: I am the author)
huxtable::quick_pdf(iris[1:10, ])
It will automatically open the PDF in your viewer – you can disable this with auto_open=FALSE.
For prettier formatting, create a huxtable object:
library(huxtable)
ht <- as_hux(iris[1:10, ])
bold(ht)[1,] <- TRUE # or whatever else you feel like doing
quick_pdf(ht)
I am trying to combine two tables in R Markdown into a single table, one below the other & retaining the header. The figure below shows the desired output. After putting my markdown code I will show the actual output. I realize that the way I have structured the pander statements will not allow me to get the output I want but searching SO I was unsuccessful in finding the right way to do so.
I can do some post processing in Word to get the output exactly as I want but I am trying to avoid that overhead.
The testdat.RData file is here: https://drive.google.com/file/d/0B0hTmthiX5dpWDd5UTdlbWhocVE/view?usp=sharing
The R Markdown RMD file is here: https://drive.google.com/file/d/0B0hTmthiX5dpSEFIcGRNQ1MzM1E/view?usp=sharing
Desired Output
```{r,echo=FALSE,message = FALSE, tidy=TRUE}
library(pander)
load("testdat.RData")
pander::pander(t1,big.mark=',', justify=c('left','right','right','right'))
pander::pander(t2,big.mark=',', justify=c('left','right','right','right'))
```
Actual Output
Thanks,
Krishnan
Here's my attempt using the xtable package:
```{r,echo=FALSE, message = FALSE, results="asis"}
library(xtable)
# Add thousands separator
t1[-1] = sapply(t1[-1], formatC, big.mark=",")
t2[-1] = sapply(t2[-1], formatC, big.mark=",")
t1$Mode = as.character(t1$Mode)
# Bind together t1, extra row of column names, and t2
t1t2 = rbind(t1, names(t1), t2)
# Render the table using xtable
print(xtable(t1t2, align="rrrrr"), # Right-align all columns (includes extra value for row names)
include.rownames=FALSE, # Don't print rownames
hline.after=NULL,
# Add midrules before/after each set column names
add.to.row = list(pos = list(-1,0,4,5),
command = rep("\\midrule \n",4)))
```
And here's the output:
Allow me to make a formal answer since my comment seemed to work for you.
pander(rbind(t1,names(t2),t2))
I am currently using knitr in R and RStudio to produce a LaTeX output. My code is a .Rnw file (called, say, testKnitr.Rnw) that is compiled to a pdf file with:
knit("testKnitr.Rnw") // in RStudio
pdflatex testKnitr.tex // in terminal
I would like to use an if-else syntax in LaTeX so that, depending on the value of an R variable, one of two LaTeX text paragraphs are output. In these LaTeX paragraphs, I would like to use expressions like \Sexpr{} and and \ref.
I have a minimal-working-example that is based on the second answer to a similar question posted here:
How to write an if-then statement in LaTeX using the value of an R variable in knitr/Sweave
Here is the MWE:
\documentclass{article}
\begin{document}
<<include=FALSE>>=
library(knitr)
opts_chunk$set(
concordance=TRUE
)
#
<<condition, include=FALSE, echo=FALSE>>=
x<- rnorm(1)
if(x>0){
text <- "This means x value of \Sexpr{x} was greater than 0"
}else{
text <- "This means x value of \Sexpr{x} was less than 0"
}
#
Testing the code:
<<print, results='asis', echo=FALSE>>=
cat(text)
#
\end{document}
Ideally, the intended output of the above MWE would a report with one line that contained something like:
"This means x value of 0.87 was greater than 0"
or
"This means x value of -0.87 was less than 0"
Before answering this question, I would like to take a look at the meta-question of whether this should be done.
Should we do it?
I don't think so. What we are basically doing here is using knitr to insert \Sexpr{x} in a document and then interpret \Sexpr{x}. There are no (obvious) reasons why we should take this detour instead of inserting the value of x directly to the document.
How to do it?
The following minimal example shows how it could be done anyways:
\documentclass{article}
\begin{document}
<<setup, echo = FALSE>>=
library(knitr)
knit_patterns$set(header.begin = NULL)
#
<<condition, echo=FALSE>>=
x <- rnorm(1)
if (x > 0) {
text <- "This means x value of \\Sexpr{x} was greater than 0"
} else {
text <- "This means x value of \\Sexpr{x} was less than 0"
}
#
Testing the code:
<<print, results='asis', echo=FALSE>>=
cat(text)
#
\end{document}
Two things are important here:
We need to escape the backslash in \Sexpr, resulting in \Sexpr.
We need to set knit_patterns$set(header.begin = NULL).
To compile the document:
Save it as doc.Rnw.
Then execute:
knitEnv <- new.env()
knit(input = "doc.Rnw", output = "intermediate.Rnw", envir = knitEnv)
knit2pdf(input = "intermediate.Rnw", output = "doc_final.tex", envir = knitEnv)
What happens?
The first call of knit generates intermediate.Rnw with the following content:
\documentclass{article}
\begin{document}
Testing the code:
This means x value of \Sexpr{x} was less than 0
\end{document}
You should note that knitr didn't include any definitions, commands etc. as usual to the LaTeX code. This is due to setting header.begin = NULL and documented here. We need this behavior because we want to knit the resulting document again in the second step and LaTeX doesn't like it when the same stuff is defined twice.
Creating the new environment knitEnv and setting it as envir is optional. If we skip this, the variable x will be created in the global environment.
In the second step we use knit2pdf to knit intermediate.Rnw and immediately generate a PDF afterwards. If envir was used in the first step, we need to use it here too. This is how x and it's value are conveyed from the first to the second knitting step.
This time all the gory LaTeX stuff is included and we get doc_final.tex with:
\documentclass{article}\usepackage[]{graphicx}\usepackage[]{color}
%% maxwidth is the original width if it is less than linewidth
%% otherwise use linewidth (to make sure the graphics do not exceed the margin)
\makeatletter
\def\maxwidth{ %
\ifdim\Gin#nat#width>\linewidth
\linewidth
\else
\Gin#nat#width
\fi
}
\makeatother
%% more gory stuff %%
\IfFileExists{upquote.sty}{\usepackage{upquote}}{}
\begin{document}
Testing the code:
This means x value of \ensuremath{-0.294859} was less than 0
\end{document}
I have a data frame that has demographic information split into 16 groups. I basically need to iterate over these groups and create a PDF page for each group. I've tried using Rhtml but so far I can only get one page to generate. Is there a way to use templates or something?
When you need PDF output, why don't you directly compile .Rnw to .pdf?
Here an example using the iris dataset. It prints the first few rows of each species on a new page:
\documentclass{article}
\begin{document}
<<results = "asis", echo = FALSE>>=
library(xtable)
newpage <- ""
invisible(lapply(unique(iris$Species), FUN = function(x) {
cat(newpage)
cat(sprintf("\\section{%s}", x))
current <- head(subset(x = iris, subset = Species == x))
print(xtable(current))
newpage <<- "\\clearpage"
}))
#
\end{document}
I additionally used xtable to easily get a nicely formatted table. The output looks like this:
I have several pre-made figures, which I'd like to add to a latex document that I'm preparing with knitr.
What is the best strategy to add them using something like a for loop?
Thanks a lot!
My suggestion is to build a data frame to support the meta data about the needed LaTeX figure environments and then use mapply with a custom function to build the needed output. Here is an example .Rnw file
\documentclass{article}
\usepackage{hyperref,fullpage}
\hypersetup{
colorlinks=true,
linkcolor=blue,
filecolor=magenta,
urlcolor=cyan,
}
\begin{document}
Thanks to \url{https://classroomclipart.com} for the graphics.
For displaying several pre-made figures you could write out the figure
environments yourself.
\begin{figure}[!h]
\centering
\caption{Explicit figure environment. \label{fig:00}}
\includegraphics[width=0.2\linewidth]{figs/man-working-on-a-computer-clipart-318.jpg}
\end{figure}
To create many figure environments, I would suggest building a data.frame with
captions, figure labels, options, and file paths:
<<>>=
myfigs <-
data.frame(caption = c("Bright Red Fall Foliage", "Chat 9", "Man On Computer"),
label = c("brff", "c9", "moc"),
option = c("width=0.1\\linewidth", "width=0.2\\linewidth", "width=0.3\\linewidth"),
path = c("figs/bright-red-fall-foliage-photo_8304-Edit.jpg",
"figs/chat-9-94.jpg",
"figs/man-working-on-a-computer-clipart-318.jpg"),
stringsAsFactors = FALSE)
myfigs
#
Build a function for creating a figure environment:
<<>>=
build_fig_env <- function(caption = "", label = "", option = "", path = "") {
cat(
sprintf("\\begin{figure}[!h]\n\\centering\n\\caption{%s \\label{fig:%s}}\n\\includegraphics[%s]{%s}\n\\end{figure}\n\n\n",
caption, label, option, path)
)
}
#
Now call the function using mapply. The mapply call is wrapped in a call to
invisible to suppress the irrelevant output.
<<results = "asis">>=
invisible(
mapply(build_fig_env,
caption = myfigs$caption,
label = myfigs$label,
option = myfigs$option,
path = myfigs$path,
SIMPLIFY = FALSE)
)
#
This is just one solution to your question.
\end{document}
The output looks like this:
Or you can view the pdf here