I am preparing a .Rmd document that begins with an executive summary. I would like to include some inline R code to present a few of the key results up front; however, those results are calculated as part of the body later in the document.
Is there any way to present a result in the rendered document out of order/sequence with the actual calculation?
You could use chunk reuse in knitr (see http://yihui.name/knitr/demo/reference/). Here you would put your chunks to analyze first but not create the output, then output the summary, then the details. Here is some quick markdown knitr code to show this:
```{r chunk1, echo=FALSE, results='hide'}
x <- rnorm(1)
x
```
the value of x is `r x`.
```{r chunk2, ref.label='chunk1', echo=TRUE, results='markup', eval=2}
```
Note that the code will be evaluated twice unless you take steps to prevent this (the eval=2 in my example).
Another option would be to create 2 child documents, the first runs your main code and creates the output, the second creates the summary. Then in your parent document you include the summary first, then the detail part. I think that you will need to run knitr on these by hand so that you do it in the correct order, the automatic child document tools would probably run in the wrong order.
Related
I'm having a problem with assigning LaTeX environments within an RMarkdown for-loop code-chunk.
In short, I've written an R Markdown document and a series of R-scripts to automatically generate PDF reports at the end of a long data analysis pipeline. The main section of the report can have a variable number of sections that I'm generating using a for-loop, with each section containing a \subsection heading, a datatable and plot generated by ggplot. Some of these sections will be very long (spanning several pages) and some will be very short (~1/4 of a page).
At the moment I'm just inserting a \pagebreak at the end of each for-loop iteration, but that leaves a lot of wasted space with the shorter sections, so I'm trying to "group" each section (i.e. the heading, table and chart) so that there can be several per page, but they will break to a new page if the whole section won't fit.
I've tried using a figure or minipage environment, but for some reason those commands are printed as literal text when the plot is included; these work as expected with the heading and data table, but aren't returned properly in the presence of the image.
I've also tried to create a LaTeX samepage environment around the whole subsection (although not sure this will behave correctly with multi-page sections?) and then it appears that the Markdown generated for the plot is not interpreted correctly somewhere along the way (Pandoc?) when it's within that environment and throws an error when compiling the TeX due to the raw Markdown ![]... image tag.
Finally, I've also tried implementing \pagebreak[x] and \nopagebreak[y] hints at various points in the subsection but can't seem get these to be produce the desired page breaking behaviour.
I've generated an MWE that reproduces my issues below.
I'd be really grateful for any suggestions on how to get around this, or better ways of approaching "grouping" of elements that are generated in a dynamic fashion like this?
---
title: "Untitled"
author: "I don't know what I'm doing"
date: "26/07/2020"
output:
pdf_document:
latex_engine: xelatex
---
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = FALSE, dev = "cairo_pdf")
```
```{r cars, results='asis'}
for (i in 1:5){
cat("\\begin{figure}")
cat(paste0("\\subsection{This is subsection ",i,"}"))
cat("\\Huge Here's some bulk text that would represent a data table... kasvfkwsvg fiauwe grfiwgiu iudaldbau iausbd ouasbou asdbva asdbaisd i iuahihai hiuh iaiuhqijdblab ihlibljkb liuglugu h uhi uhi uhqw iuh qoijhoijoijoi qwegru wqe grouw egq\\newline")
plot(mtcars$wt,mtcars[,i])
cat("\\end{figure}")
}
```
Edit to add: interestingly these figure and minipage environments seems to work as expected when executing the same example in an .Rnw using knitr... so does that narrow it down to an issue with Pandoc? Again, any help much appreciated!
What happens is that the raw TeX commands are not treated as TeX when going through Markdown. You can fix that by explicitly marking the relevant snippets as LaTeX:
for (i in 1:5){
cat("`\\begin{figure}`{=latex}")
cat(paste0("\\subsection{This is subsection ",i,"}"))
cat("\\Huge Here's some bulk text that would represent a data table... kasvfkwsvg fiauwe grfiwgiu iudaldbau iausbd ouasbou asdbva asdbaisd i iuahihai hiuh iaiuhqijdblab ihlibljkb liuglugu h uhi uhi uhqw iuh qoijhoijoijoi qwegru wqe grouw egq\\newline")
plot(mtcars$wt,mtcars[,i])
cat("`\\end{figure}`{=latex}")
}
See the generic raw attribute section in the pandoc manual for details.
I'm editing an R markdown file (.Rmd) that has a lot of R code blocks to move groups of those code blocks into "child" documents to simplify rearranging sections (if nothing else). As I convert sections to child documents, I would like to test the new child document without running the rest of the blocks and other children. However, when I use to comment out those sections, the R blocks still run (but RStudio makes the sections "look" as though they were commented out).
If I eliminate the preceding and trailing "```"s (i.e., the code block signifiers), the commenting works fine. However, as I said, I've got lots of code blocks and something like would be more convenient.
So, how do I comment out the R code blocks so they won't run?
In RStudio, if you highlight from (at least) one row above an R code chunk to (at least) the last row of the R code chunk,1 and then type ctrl-shift-C (in OSX or Windows) or command-shift-C (OSX only), RStudio will place html comment tags on the chunk.
For example:
```{r cars}
summary(cars)
plot(pressure)
```
After highlighting this and type ctrl-shift-C, this becomes:
<!-- ```{r cars} -->
<!-- summary(cars) -->
<!-- plot(pressure) -->
<!-- ``` -->
To selectively comment out multiple chunks, you can use the RStudio find/replace tool with the regex option checked. It takes two replacement steps (it can probably be done in one step, but I'm not sure how to do a regex to capture across multiple lines in RStudio).
Step 1: Comment out the first line of one or more chunks:
Find: (```{r.*)
Replace: <!--\1
Step 2: Comment out the last line of one or more chunks:
Find: (```)$
Replace: \1-->
1 You must include the row above the chunk in the highlight. Otherwise, RStudio will place R comment tags (#) at the beginning of each row of the chunk and the commented lines will appear as plain text in the output document.
In an Rmarkdown document, we can apply certain options to each R code chunk that determines whether the code inside will be run, printed, show error messages, etc.
To have a specific code chunk not run, use:
```{r cars, eval=FALSE}
summary(cars)
```
To have a specific code chunk not run or print into the created doc, use:
```{r cars, eval=FALSE, echo=FALSE}
summary(cars)
```
"TRUE" is used for the opposite effects and is the default.
If you have many code chunks you need to comment out, you can take the suggestion from #eipi10 (thanks) and use find/replace with the regex option selected. So, the find would be "(```{r.*)", and the replace would be "\1, eval=FALSE, echo=FALSE}" (without the double quotes).
I created a custom function which sets mfrow to nxn and creates n^2 scatter plots, with multiple data sets on each plot, based on an input list of data frames. The signature of my plotting function looks like this:
plot.return.list<-function(df.list,num.plot,title)
Where df.list is my list of data frames, num.plot is the total number of plots to generate (used to set mfrow) and title is the overall plot title (the function generates titles for each individual sub-graph).
This creats plots fine when I run the function from the console. However, I'm trying to get this figure into a markdown document using RStudio, like so:
```{r, fig.height=6,fig.width=6}
plot.return.list(f.1.list,4,bquote(atop("Numerical Approximations vs Exact Soltuions for "
,dot(x)==-1*x*(t))))
```
Since I haven't set the echo option in my {r} statement, this prints both the plotting code as well as the plot itself. However, if my first line instead reads:
{r, fig.height=6,fig.width=6,echo=FALSE}
Then both the code AND the plot disappear from the final document.
How do I make the plot appear WITHOUT the code? According to the example RStudio gives, setting echo=FALSE should make the plot appear without the code, but that isn't the behavior I'm observing.
EDIT: I seem to have tracked my problem down to kable. Whether or not I'm making a custom plot-helper function, any call to kable kills my plot. This can be reproduced in a markdown:
---
title: "repro"
author: "Frank Moore-Clingenpeel"
date: "October 9, 2016"
output: pdf_document
---
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
library(knitr)
options(default=TRUE)
repro.df<-data.frame((0.1*1:10)%*%t(1:10))
```
```{r, echo=FALSE}
kable(repro.df)
```
```{r, fig.height=6,fig.width=6,echo=FALSE}
plot(repro.df[,1],repro.df[,2])
```
In this code, the plot won't plot because I have echo set to false; removing the flag makes the plot visible
Also note that in my repro code, kable produces a table with a bunch of garbage in the last line--I don't know why, but this isn't true for my full original code, and I don't think it's related to my problem.
Thanks for the reproducible example. From this I can see that the problem is you don't have a newline between your table chunk and your plot chunk.
If you were to knit this and examine the MD file produced by knit (or set html_document as your output format and have keep_md: true to look at it), you would see that the table code and plot code are not separated by any newline. Pandoc needs this to delimit the end of the table. Without it, it thinks your ![](path/to/image.png) is part of the table and hence puts it as a "junk line" in the table rather than an image on its own.
Just add a newline between the two chunks and you will be fine. (Tables need to be surrounded with blank lines).
(I know you are compiling to LaTeX so it may confuse you why I am talking about markdown. In case it does, when you do Rmd -> PDF, Rmarkdown uses knit to go from RMD to MD, and then pandoc to go from MD to tex. This is why you still need to make sure your markdown looks OK).
I'm writing a report in R Markdown in which I don't want to print any of my R code in the main body of the report – I just want to show plots, calculate variables that I substitute into the text inline, and sometimes show a small amount of raw R output. Therefore, I write something like this:
In the following plot, we see that blah blah blah:
```{r snippetName, echo=F}
plot(df$x, df$y)
```
Now...
That's all well and good. But I would also like to provide the R code at the end of the document for anybody curious to see how it was produced. Right now I have to manually write something like this:
Here is snippet 1, and a description of what section of the report
this belongs to and how it's used:
```{r snippetName, eval=F}
```
Here is snippet 2:
```{r snippetTwoName, eval=F}
```
<!-- and so on for 20+ snippets -->
This gets rather tedious and error-prone once there are more than a few code snippets. Is there any way I could loop over the snippets and print them out automatically? I'm hoping I could do something like:
```{r snippetName, echo=F, comment="This is snippet 1:"}
# the code for this snippet
```
and somehow substitute the following result into the document at a specified point when it's knitted:
This is snippet 1:
```{r snippetName, eval=F}
```
I suppose I could write some post-processing code to scan through the .Rmd file, find all the snippets, and pull out the code with a regex or something (I seem to remember there's some kind of options file you can use to inject commands into the pandoc process?), but I'm hoping there might be something simpler.
Edit: This is definitely not a duplicate – if you read my question thoroughly, the last code block shows me doing exactly what the answer to the linked question suggests (with a slight difference in syntax, which could have been the source of the confusion?). I'm looking for a way to not have to write out that last code block manually for all 20+ snippets in the document.
This is do-able within knitr, no need to use pandoc. Based on an example posted by Yihui at https://github.com/yihui/knitr-examples/blob/master/073-code-appendix.Rnw
Set echo=FALSE throughout your document: opts_chunk$set(echo = FALSE)
Then put this chunk at the end to print all code:
```{r show-code, ref.label=all_labels(), echo = TRUE, eval=FALSE}
```
This will print code for all chunks. Currently they all show up in a single block; I'd love to figure out how to put in the chunk label or some other header... For now I start my chunks with comments (probably not a bad idea in any case).
Updated: to show only the chunks that were evaluated, use:
ref.label = all_labels(!exists('engine')) - see question 40919201
Since this is quite difficult if not impossible to do with knitr, we can take advantage of the next step, the pandoc compilation, and of pandoc's ability to manipulate content with filters. So we write a normal Rmd document with echo=TRUE and the code chunks are printed as usual when they are called.
Then, we write a filter that finds every codeblock of language R (this is how a code chunk will be coded in pandoc), removes it from the document (replacing it, here, with an empty paragraph) and storing it in a list. We then add the list of all codeblocks at the end of the document. For this last step, the problem is that there really is no way to tell a python filter to add content at the end of a document (there might be a way in haskell, but I don't know it). So we need to add a placeholder at the end of the Rmd document to tell the filter to add the R code at this point. Here, I consider that the placeholder will be a CodeBlock with code lastchunk.
Here is the filter, which we could save as postpone_chunks.py.
#!/usr/bin/env python
from pandocfilters import toJSONFilter, Str, Para, CodeBlock
chunks = []
def postpone_chunks(key, value, format, meta):
if key == 'CodeBlock':
[[ident, classes, keyvals], code] = value
if "r" in classes:
chunks.append(CodeBlock([ident, classes, keyvals], code))
return Para([Str("")])
elif code == 'lastchunk':
return chunks
if __name__ == "__main__":
toJSONFilter(postpone_chunks)
Now, we can ask knitr to execute it with pandoc_args. Note that we need to remember to add the placeholder at the end of the document.
---
title: A test
output:
html_document:
pandoc_args: ["--filter", "postpone_chunks.py"]
---
Here is a plot.
```{r}
plot(iris)
```
Here is a table.
```{r}
table(iris$Species)
```
And here are the code chunks used to make them:
lastchunk
There is probably a better way to write this in haskell, where you won't need the placeholder. One could also customize the way the code chunks are returned at the end to add a title before each one for instance.
I am trying to write a report in rmarkdown and then use knitr to generate a pdf.
I want all the code to be pushed to the "End of the document", while just displaying results interweaved with my text. The echo='hold' option doesn't do this.
Section of my markdown file
Generate data
```{r chunk1,echo='hold',R.options=}
num_seq<-rnorm(100,0.2)
num_seq
```
We further report the mean of these numbers.
```{r,echo='hold' }
mean(num_seq)
```
I have tried to read the the relevant documentation found here http://yihui.name/knitr/options/, but I can't figure out how to do this.
I don't think echo='hold' is an option. Regardless, the trick is to use echo=FALSE where the code is included, and then re-use the same chunk name and use eval=FALSE where you want the code to be printed. (Other options in both locations are fine, but these two are the minimum required.)
The following evaluates the code (and optionally includes output from it) where the chunk is located, but doesn't include the code until you specify.
# Header 1
```{r chunk1, echo=FALSE}
x <- 1
x + 5
```
This is a test.
```{r chunk1, eval=FALSE}
```
Results in the following markdown:
Header 1
========
## [1] 6
This is a test.
x <- 1
x + 5
Edit: I use this frequently in R markdown documents with randomness: I store the random seed in the very beginning (whether I set it manually or just store the current random state for later reproduction) and display it in an annex/appendix:
# Header 1
```{r setseed, echo=FALSE, include=FALSE}
set.seed(seed <- sample(.Machine$integer.max, size=1))
seed
```
This is a test `r seed`.
# Annex A {-}
```{r showsetseed, ref.label='setseed', eval=FALSE}
```
```{r printseed, echo=FALSE}
seed
```
This example doesn't include the results with the original code chunk. Unfortunately, the results aren't stored, and if I set eval=TRUE when I use the same chunk name later, it will calculate and present a different seed. That's why the printseed block. The reason I explicitly "show" seed in the first setseed block is solely so that, in the annex, the showsetseed and printseed chunks flow well. (Otherwise, set.seed does not return a number, so it would have looked wierd.)
BTW: this second example uses ref.label, which Yihui documents here as a more general approach to chunk reuse.
BTW #2: when I said "store the random state", that's not completely correct ... I'm storing a randomly-generated seed. The random state itself is much larger than a single integer, of course. I don't want to anger the PRNG gods :-)