sink() won't print output to text file in rmarkdown - r

Say I have a simple rmarkdown document called test.Rmd
---
output: pdf_document
---
This code tries to save output to a file called 'example.txt'
```{r}
sink(file='example.txt')
sink.number()
library(MASS)
summary(cars)
sink()
sink.number()
```
If I run this in RStudio (using the knit PDF button) then I get lots of output but I believe the most important is the following (I can include the other output on request)
processing file: test.Rmd
"C:/Program Files/RStudio/bin/pandoc/pandoc" +RTS -K512m -RTS test.utf8.md --to latex --from markdown+autolink_bare_uris+ascii_identifiers+tex_math_single_backslash --output test.pdf --template "C:\Users\wammonj\Documents\R\win-library\3.2\rmarkdown\rmd\latex\default.tex" --highlight-style tango --latex-engine pdflatex --variable graphics=yes --variable "geometry:margin=1in"
output file: test.knit.md
Output created: test.pdf
Warning message:
In sink() : no sink to remove
The file example.txt is made but the output is not in there while Rmarkdown made a file called test.pdf with the output of summary(cars) in it.
Is that the problem? Does Rmarkdown use sink() to make its documents? Is there a way around this so the output will appear in both the pdf file and the text file?
Addition: It looks like from #r2evans comment that rmarkdown does indeed use sink(). I have played with sink() a little and it seems like you can have multiple diversions going at the same time but you can only write to the one that was most recently activated (see example below).
So it seems from the output that Rmarkdown closes my sink down right away because when I look at sink.number() then it is always one.
I am still trying to find a workaround for this so any help would be nice.
Example of multiple diversions:
sink(file = 'example1.txt')
sink(file = 'example2.txt')
sink.number() # prints 2 to example2.txt
x = seq(1,10)
x # prints to example2.txt
sink()
sink.number() # prints 1 to example1.txt
y = sum(x)
y # prints to example1.txt
sink()
sink.number() # prints 0 to R console

I run into a similar issue. One solution of saving the output to local files is to use write.csv() function instead, which also works with non-csv files.
The R code below tries to save output to a file called 'example.txt'.
write.csv(data.frame(data_to_save), file='example.txt')

This issue is due to (I believe) an error in the evaluate package's use of sink(), combined with rmarkdown::render's line-by-line evaluation.
rmarkdown::render() will submit each line to evaluate::evaluate at a time, but evaluate will fail if a new sink() is created but not closed within that line. A workaround is to define these steps as a function in which both the initial sink(...) and the final sink() are submitted in one line. Of course all of the code you are attempting to capture the results of will need to be in the same function as well.
Alternately, wait to see if the rmarkdown or evaluate developers fix the issue:
https://github.com/r-lib/evaluate/issues/104
https://github.com/rstudio/rmarkdown/issues/2243

I wanted to do a parametric rendering of rmarkdown. The parameter would be a random number. I needed to save/see the output (a vector of number and string) to a file (save_out.txt).
str00 = c('test','some','here',2323)
cat(str00,file="save_out.txt",sep=",",append=TRUE)
cat('\n',file="save_out.txt",append=TRUE)
Result:
> test,some,here,2323
sink or writeLines do not work for me when I want to append data while rendering the rmarkdown.
I got some help from here: https://stackoverflow.com/a/55225065/1247080

Related

Why does rendering a pdf from rmarkdown require closing rstudio between renders?

Background
I am trying to make a rmarkdown document that is rendered using render(). The render call has two elements that are parameterized:
I would like the user to be able to specify pdf or html.
Straightforward using output_format().
I also would like to pass a parameter to the document to specify if the tables (using the kableExtra package) are latex or html.
This is the rmarkdown file called test.Rmd
---
title: "Title"
author: "Zzz Zzzzzz"
params:
table_format:
value
---
```{r setup}
knitr::opts_chunk$set(echo = FALSE)
library(knitr)
library(kableExtra)
options(knitr.table.format = params$table_format)
```
## Test table
```{r cars}
if (params$table_format == "latex"){
kable(iris[1:100,], booktabs = T) %>%
kable_styling(latex_options = c("scale_down"))
}
if (params$table_format == "html"){
kable(iris[1:100,]) %>%
kable_styling(bootstrap_options = c("striped", "hover")) %>%
scroll_box(width = "500px", height = "600px")
}
params$table_format
```
Now here are the two calls to render the file:
rmarkdown::render("test.Rmd", output_format = "pdf_document", params = list(
table_format = "latex"
))
rmarkdown::render("test.Rmd", output_format = "html_document", params = list(
table_format = "html"
))
Problem
Now if I open up a fresh rstudio session I can run both render calls no problem. Either .pdf or an .html file is created. However if I then try to run the .pdf render again i get the following error:
"C:/Program Files/RStudio/bin/pandoc/pandoc" +RTS -K512m -RTS
test.utf8.md --to latex --from
markdown+autolink_bare_uris+ascii_identifiers+tex_math_single_backslash
--output test.pdf --template "C:\Users\salbers\R\win-library\3.4\rmarkdown\rmd\latex\default-1.17.0.2.tex"
--highlight-style tango --latex-engine pdflatex --variable graphics=yes --variable "geometry:margin=1in" ! Undefined control
sequence. \begin {tabular}{rrrrl} \toprule
Sepal.Length & Sepal.Width & Pet... l.267 \end{tabular}}
pandoc.exe: Error producing PDF Error: pandoc document conversion
failed with error 43 In addition: Warning message: running command
'"C:/Program Files/RStudio/bin/pandoc/pandoc" +RTS -K512m -RTS
test.utf8.md --to latex --from
markdown+autolink_bare_uris+ascii_identifiers+tex_math_single_backslash
--output test.pdf --template "C:\Users\salbers\R\win-library\3.4\rmarkdown\rmd\latex\default-1.17.0.2.tex"
--highlight-style tango --latex-engine pdflatex --variable graphics=yes --variable "geometry:margin=1in"' had status 43
The html render works fine over and over again. If I close rstudio, then ropen the project, the render for pdf work fine as well.
Question
Can anyone tell me why my pdf rendered rmarkdown document can't be rendered twice in a single session of rstudio?
Similarly, why does rstudio have to closed in between renderings?
2019-01-21 UPDATE:
One of the big difference between the knit button and the render function is that, the knit button always starts with a "new environment" (as we all can feel) while the render function by default starts in the parent.env().
render(input, ..., envir = parent.frame(), ...)
In the function documentation, we see
envir
The environment in which the code chunks are to be evaluated
during knitting (can use new.env() to guarantee an empty new
environment).
Therefore, we can simulate the behavior of clicking the knit button by putting envir = new.nev() in the render call.
Original Answer:
Hmm, let me post the solution first. To solve this behavior, you need to put the following stuff in your yaml section. I also added a function kableExtra_latex_packages() in the dev version earlier this week to bring up the following texts.
header-includes:
- \usepackage{booktabs}
- \usepackage{longtable}
- \usepackage{array}
- \usepackage{multirow}
- \usepackage[table]{xcolor}
- \usepackage{wrapfig}
- \usepackage{float}
- \usepackage{colortbl}
- \usepackage{pdflscape}
- \usepackage{tabu}
- \usepackage{threeparttable}
- \usepackage[normalem]{ulem}
If you are curious why there is such an odd behavior, here is a short explanation. When you first load kableExtra in a rmarkdown environement, it will try to put the LaTeX package information above into the rmarkdown metadata using the usepackage_latex() function that comes with this package. It works fine if you just hit the knit button because every "knit+rendering" process is supposed to be isolated. However, surprisingly (btw thanks for bringing it up), as we see it here, if you are trying to render from console, since (my assumption) knitr or rmarkdown is trying to reuse some cached results, this process failed to replicate. It turns out these LaTeX package dependencies were not put into the tex file being generated and ends up with an error. If you close RStudio and restart it, of course, the temporary memory it has will be gone and you should be able to load those packages again. I feel like it could be a global-variable-related bug in rmarkdown. I guess we can fix it by adding a "forget the meta" part at the end of the render function but I need to look it that.
Part of it was my bad for not providing enough documentations on LaTeX packages that were used in past releases. Now, I added a new section about this issue at the very beginning of the package vignette of kableExtra 0.5.0, which was released earlier this week. Feel free to check it out. Also, as I said earlier, in current dev version, you can bring up the list using the function kableExtra_latex_packages().
In my case, #Hao answer didn't work...I finally managed unloading the kableExtra package after each render execution, as follows:
rmarkdown::render('torender.Rmd')
detach("package:kableExtra", unload=TRUE)
It should be possible also selecting the environment using something like
rmarkdown::render('torender.Rmd',envir=new.env(some parameters))
which is cleaner....but I didn't manage this way!
I had a similar problem: a loop to render PDF reports that contained a table. PDF would not render with booktabs = T. My solution was to manually load all of the latex packages in my setup chunk in the Rmd script that was being called from the loop.
So in the Rmd script that was being called multiple time I have:
usepackage_latex("booktabs")
usepackage_latex("longtable")
usepackage_latex("array")
usepackage_latex("multirow")
usepackage_latex("xcolor", "table")
usepackage_latex("wrapfig")
usepackage_latex("float")
usepackage_latex("colortbl")
usepackage_latex("pdflscape")
usepackage_latex("tabu")
usepackage_latex("threeparttable")
usepackage_latex("threeparttablex")
usepackage_latex("ulem", "normalem")
usepackage_latex("makecell")
This fixed the issue - the PDFs rendered with formatted tables.
Hopefully, this helps someone.
I found an easy way to do this for multiple .Rmd files was to make a "headers.tex" file with the list of these kableExtra-added \usepackage{} commands. Then in the YAML header of the .Rmd file:
output:
pdf_document:
includes:
in_header: headers.tex
Here's what I put in the header.tex file -- I'd copied it from one that worked, and it's also the output of kableExtra_latex_packages() stripping off the "header-includes:" line and the dashes.
\usepackage{booktabs}
\usepackage{longtable}
\usepackage{array}
\usepackage{multirow}
\usepackage{wrapfig}
\usepackage{float}
\usepackage{colortbl}
\usepackage{pdflscape}
\usepackage{tabu}
\usepackage{threeparttable}
\usepackage{threeparttablex}
\usepackage[normalem]{ulem}
\usepackage{makecell}
\usepackage{xcolor}

run an R Markdown (check.Rmd ) and an R knitr (test.Rnw ) file together

I have the following problem; There are 2 big documents, one written in R Markdown (check.Rmd ) and the other in R knitr (test.Rnw ). In the first doc we have a code like the following:
\section{Organisations Test}
\textbf{Running Organisations Checks}
<<CreateOrganisations, echo=FALSE, progress=TRUE, warning=FALSE, eval=TRUE>>=
source("OrganisationsTest.R")
OrganisationsTest(current_schema,server,user,pass)
#
and in the other as follows:
2. check the downwards shock
```{r chunk_Int_Sh_p2, echo=FALSE}
unique(param.int.shock.tab[SHOCKTYPE=="SHOCK_DOWN"&PERIODEND<21|PERIODEND==90, list( Maturity=PERIODEND, Shock_value=100*SHOCKVALUE)])
```
Now the question: how can I combine both so that I have just one script which runs and compile both one after each other. Just for clarification, I mean without any changes in both documents how can I have just one script which applyes to the first doc knit PDF to create pdf and to the other one CompilePDF ?
I suppose in Linux one can write a shell script but what a bout using RStudio in windowes?
I am really grateful for every hint I am a little bit helpless!
Addendum: In principle it is as follows: we have 2 files if you would compile a knitr file you would use bottom in RStudio, and for a Markdown file one may use bottom in RStudio, BUT we want to put both together and klick on one bottom. How is it possible?
The RStudio buttons "Compile PDF" (for RNW documents) and "Knit PDF" (for RMD documents) are convenient, but in cases like this one it is important to understand what they do in order to reproduce the same or similar behavior.
Summing the question up, it asks for a way to convert two files (a RMD and a RNW document) to PDF, preferably using a button like the two buttons mentioned above.
Unfortunately, (up to my knowledge) it is not possible to add any user-defined buttons to the RStudio GUI. But it is straightforward to write an R script that compiles both documents.
In the following I assume two files:
first.Rmd:
This is a RMD file.
```{r, echo=FALSE}
plot(1)
```
second.Rnw:
\documentclass{article}
\begin{document}
This is a RNW file.
<<>>=
plot(1)
#
\end{document}
To compile first.Rmd to PDF, we need the following (see How to convert R Markdown to PDF?):
library(knitr)
library(rmarkdown)
knit(input = "first.Rmd")
render(input = "first.md", output_format = "pdf_document")
The knit call generates first.md from first.Rmd, execting the R code in the chunks. render converts the resulting markdown file to PDF. [Note the addendum at the bottom!]
To compile first.Rnw to PDF, we can simply use knit2pdf:
knit2pdf("second.Rnw")
Copying both snippets into one R script and clicking "Source" is as close as possible to a "one-button-solution".
However, note that the snippets do something very similar to the "Compile / knit PDF" button, but it is not identical. The "Compile" buttons start a new R session while the solution above uses the current session.
Before executing the snippets make sure to use the correct working directory.
Both knit and knit2pdf by default use envir = parent.frame(). That means R code in chunks is executed in the calling enironment (see What is the difference between parent.frame() and parent.env() in R). This can be a useful feature, for example to "pass" variables to chunks, but it is important to know about it. Otherwise a document might compile just fine in one session (where certain variables exist in the calling environment) but cannot be compiled in another session (that is missing these variables). Therefore, this feature is a little bit dangerous in terms of reproducibility. As a solution, envir = new.env(parent = as.environment(2)) could be used; see knitr inherits variables from a user's environment, even with envir = new.env() for more details on that topic.
I just realized to following about render:
If the input requires knitting then knit is called prior to pandoc.
(Source: ?render)
Therefore, knit(input = "first.Rmd"); render(input = "first.md", output_format = "pdf_document") can be simplified to render(input = "first.Rmd", output_format = "pdf_document"). The envir issues of knit from above apply to render as well.

Using knit2pdf with Rmd files

Is it possible to use the knitr function knit2pdf() directly with R Markdown (Rmd) files? I've seen various tutorials/class notes that seem to suggest it can e.g. here and here (Ctrl+F "knit2pdf" in either).
But when I take a simple rmd file (saved as "test.rmd")
---
title: "knit2pdf test"
author: "A Aaronson"
date: "Thursday, February 19, 2015"
output: pdf_document
---
This is an R Markdown document. Markdown is a simple formatting syntax for authoring HTML, PDF, and MS Word documents. For more details on using R Markdown see <http://rmarkdown.rstudio.com>.
When you click the **Knit** button a document will be generated that includes both content as well as the output of any embedded R code chunks within the document. You can embed an R code chunk like this:
```{r}
summary(cars)
```
You can also embed plots, for example:
```{r, echo=FALSE}
plot(cars)
```
Note that the `echo = FALSE` parameter was added to the code chunk to prevent printing of the R code that generated the plot.
and try
library(knitr)
knit2pdf("test.Rmd")
I get the following error
results in:
output file: test.md
Error: running 'texi2dvi' on 'test.md' failed
LaTeX errors:
! Emergency stop
*** (job aborted, no legal \end found)
! ==> Fatal error occurred, no output PDF file produced!
! ==> Fatal error occurred, no output PDF file produced!
In addition: Warning message:
running command '"C:\PROGRA~2\MIKTEX~1.9\miktex\bin\texi2dvi.exe" --quiet --pdf "test.md" --max-iterations=20 -I "C:/PROGRA~1/R/R-31~1.2/share/texmf/tex/latex" -I "C:/PROGRA~1/R/R-31~1.2/share/texmf/bibtex/bst"' had status 1
Clicking the "Knit PDF" button always successfully generates a pdf. So am I missing an intermediate step?
I should add that knit2pdf() with Rnw files is working as expected for me, though I do still get the warning
running command '"C:\PROGRA~2\MIKTEX~1.9\miktex\bin\texi2dvi.exe" --quiet --pdf "rnwtest.tex" --max-iterations=20 -I "C:/PROGRA~1/R/R-31~1.2/share/texmf/tex/latex" -I "C:/PROGRA~1/R/R-31~1.2/share/texmf/bibtex/bst"' had status 1
Help greatly appreciated.
Your input file is in rmarkdown format.
You should use the render() function in the rmarkdown package to compile your document.
Try:
library("rmarkdown")
render("temp.rmd")

rstudio knitr Error: pandoc document conversion failed with error 43

Windows7 Prof 64-bit
Rstudio Version 0.98.1091
Hello all,
I am receiving the following error when I try to use KnitR to create a PDF.
Error: pandoc document conversion failed with error 43
In addition: Warning message:
running command '"C:/Program Files/RStudio/bin/pandoc/pandoc" FirmsoftReportGenerator.utf8.md --to latex --from markdown+autolink_bare_uris+ascii_identifiers+tex_math_single_backslash-implicit_figures --output
{....}
\Documents\R\win-library\3.1\rmarkdown\rmd\latex\default.tex" --highlight-style tango --latex-engine pdflatex --variable "geometry:margin=1in"' had status 43
I have searched the forum and I found 2 references to this, and that led me to update my Rmarkdown package. However, I still receive the error.
My code consists of sourcing an R file, creating a table.
Then doing the following:
```{r outputSection, results="asis", echo=FALSE}
library(xtable)
print(xtable(overallSummary), comment=FALSE)
```
Total Raw Messages are: `r totalRawMessages`.
Any help in the right direction would be huge!
Thanks in advance
PS - The script does produce a PDF using a different CSV as a source.
The primary difference I notice with the newer source file is that one of the rownames has a space in the table I am trying to print.
PPS - When I manually replace the Row Name with spaces with "TEST1", everything works fine
rownames(overallSummary)[1] <- "TEST1"

Chunk output without knitrout and verbatim environment

<<newChunk,echo=FALSE,comment=NA,background=NA>>=
x <- "\\includegraphics[width=\\maxwidth]{figure/Kompetenz1.pdf}"
cat(x)
#
If I run this r code in my .Rnw file I will get the following output in my .tex file:
\begin{knitrout}
\definecolor{shadecolor}{rgb}{1, 1, 1}\color{fgcolor}\begin{kframe}
\begin{verbatim}
\includegraphics[width=\maxwidth]{figure/Kompetenz1.pdf}
\end{verbatim}
\end{kframe}
\end{knitrout}
How can I get just the \includegraphics{...} without any environment in my .tex file?
I am not sure why you are using Knitr in the first place. It looks like your just trying to include a PDF in your latex document. To do that I would use the command:
\includepdf[pages=-]{figure/Kompetenz1.pdf}
or
\includegraphics[width=\maxwidth]{figure/Kompetenz1.pdf}
In your Rnw file. No need for a Knitr chunk here.
The answer from #baptiste was right.
Why I was using a Knitr chunk was to loop over some values. Here is my example code:
<<Ueberblick, echo = FALSE, results = 'asis'>>=
for(i in 1:nrow(Kompetenzen)){
cat(paste("\\includegraphics[width=\\maxwidth]figure/Kompetenz.pdf}",i," \\newline ",sep=""))
}
#
Thanks for the help!

Resources