How do I explain a complicated function in Rmarkdown? - r

I have a somewhat complicated R function (different parts refer to various equations I'd like to explain.)
I want to write my code using R Markdown, but I need to be able to explain the different parts of the function in the document. A bit like literate programming.
I wonder if it is possible to split the function definition across different code chunks, or maybe insert markdown comments inside the function definition?
I'd like the end result to look something like this:
complicated = function(x) {
I use x^2 in the example so it is math, and yet short. Here it is in the actual R code:
x^2
}
This doesn't work:
``` {r}
complicated = function(x) {
```
explain the function with some math $x^$.
``` {r}
x^2
}
```
The following actually does work:
``` {r chunk1, echo=FALSE}
complicated=function(x) {
x^2
}
```
``` {r chunk1, echo=1:2, eval=F}
```
In the complicated function I use x^2 as an example.
Though it is a bit tricky, because if lines in the function change, I have to edit everything again. Also in the Rmd file, you don't actually see the code described by the comments.
Note:
Maybe it is possible to somehow have the relevant chunks written to a file without being evaluated, and then the file read in? I didn't manage to figure out a way yet...

Here's one way, though I admit it's a little bit of a hack.
---
title: "Split Function"
output: html_document
---
```{r funcdef}
myfunc <- function(x) {
x <- x + 1
x <- x * 2
return(x)
}
```
```{r funcdef1, echo = FALSE, eval = FALSE, include = FALSE}
x <- NULL
x <- x + 1
x <- x * 2
return(x)
```
First line:
```{r funcdef1, echo=2, eval = FALSE}
```
Now the last two:
```{r funcdef1, echo=3:4, eval = FALSE}
```
Done!
Explanation:
the first chunk funcdef is the full function definition, needed if we want to use it;
the second chunk includes the first line (that I do not echo, omitted with echo=-1) that is there so that the others do not err with 'x' not found (even if I do not eval or include); notice that it uses the same chunk name and has nothing in it
same for the third chunk
the reason I have to break out the body of the function without the function header and enclosing braces is that echo= using numbers allows us to subset which expressions are included, not which lines ... and a function declaration is one expression
Two things I don't really like about this:
It requires you to include the body of the function twice, so maintenance has more overhead than required;
It thinks x is being used, when all I really want is to reference the code.
Frankly, this may not be much better than including the portions of code within each subsequent chunk (and set eval=FALSE).

I found a nice answer to this question, though it looks a bit like a knitr bug. I hope it doesn't get fixed. It turns out that references to chunks work in Rmd just like in Rnw. You just have to use <<chunk name>> to refer back to a chunk.
So, here is the answer:
```{r Xsquare, eval=F}
x^2
```
We just need to take x and raise it to the second power: $x^2$.
Now let us put it together:
```{r complicated, eval=T}
complicated = function(x) {
<<Xsquare>>
}
```
Simple, right?
Turns out in Rstudio it works only when we knit everything together, but not on running a single chunk. Almost makes sense.
To solve this, in run the following: knit("filename.Rmd") in the console.

Related

Solutions to Exercises in Bookdown

How should I code solutions to exercises in the book I am writing using the bookdown package?
I'm currently writing a book using the bookdown R package. The book is broken down into chapters, and each chapter has exercises in a markdown numbered list. I would like to be able to put the solutions directly under the exercises without messing up the numbering of the problems, and in such a way that I can toggle whether the solutions are printed. I would also like to be able to pull out selected solutions (or all solutions) to form a solutions manual that gets printed out as an appendix. So far, I have two methods, which I call the "hidden R chunk method" and the "YAML method" but neither seems ideal, and can only be used to create a solutions manual.
1. Exercise one compute 1+1.
```{r, echo = FALSE, eval = FALSE}
#Solution
1+1
#BeginText The solution is `r 1 + 1`.
#EndText
```
1. Exercise two: compute 2^2.
```{r, echo = FALSE, eval = FALSE}
#Solution
2*2
#BeginText The solution is $2^2 = $`r 2*2`.
#EndText
```
I then wrote a script that pulls out anything with the #Solution comment, and breaks the #BeginText and #EndText out like this:
###Problem 1.
```{r }
1+1
```
The solution is `r 1 + 1`.
###Problem 2.
```{r }
2*2
```
The solution is $2^2 = $`r 2*2`.
and saves that in a new .Rmd file with appropriate headers.
The second solution involves YAML in between the exercises.
1. Exercise one compute 1+1.
---
solution: |
```{r}
1+1
```
The solution is `r 1 + 1`.
---
My co-author had hoped that he could pull out the YAML using an existing parser, but ended up having to write a script just like the hidden R chunk method. I'm not sure how bad of an idea it is to use YAML like this. Both solutions require that each exercise have at least a solution stub in order for the numbering to be the same.
I would like the solutions of the exercises to be connected to the exercise in some way, so that if we re-arrange the exercises or add new exercises, nothing breaks. I would also like to be able to pull out some or all of the solutions into separate markdown files that we can use to create a solutions manual.
How should we do this?

R notebook: opts_chunk has no effect

I'm working on my first R notebook which works pretty well, except for one issue.
I'd like to be the numbers that I output inline with
`r realbignumber`
to have commas as separator and max 2 decimal points: 123,456,789.12
In order to achieve this, I added a chunk at the beginning of my document, which contains...
```{r setup}
knitr::opts_chunk$set(echo = FALSE, warning=FALSE, cache = TRUE, message = FALSE)
knitr::opts_chunk$set(inline = function(x){if(!is.numeric(x)){x}else{prettyNum(round(x,1), big.mark = ",")}})
options(scipen=999)
```
The suppression of scientific numbers works like a charm, so the chunk is definitely executed. However, formatting of the inline output of numbers does not work.
Any ideas why that could be?
Do these kinds of settings generally not work with R notebooks?
Edit:
The solution suggested here also has no effect on the output format of numbers.
Here is an example illustrating two ways to print a large number in an R Markdown document. First, code to use the prettyNum() function in an inline R chunk.
Sample document where we test printing a large number. First set the number in an R chunk.
```{r initializeData}
theNum <- 1234567891011.03
options(scipen=999,digits=16)
```
The R code we'll use to format the number is: `prettyNum(theNum,width=23,big.mark=",")`.
Next, print the large number. `r prettyNum(theNum,width=23,big.mark=",")`.
The alternative of using chunk options works as follows.
Now, try an alternative using knitr chunks.
```{r prettyNumHook }
knitr::knit_hooks$set(inline = function(x) { if(!is.numeric(x)){ x }else{ prettyNum(x, big.mark=",",width=23) } })
```
Next, print the large number by simply referencing the number in an inline chunk as `theNum`: `r theNum`.
When both chunks of code are embedded in an Rmd file and knit, the output is as follows, showing that both techniques produce the same result.
regards,
Len

Include a chunk in a list RMarkdown

How do you get rmarkdown to include a code chunk as part of a list?
Example:
Something about some code - you could try this_fun
A more complicated way is to do
```{r, eval = FALSE}
a(
large(
nested(function)))
```
And that may suit your use case
Skip it all together
Originally I was using the vanilla ``` code chunk, but that gives up syntax highlighting, and inline gives up highlighting and newlines/indentation. If the code is used as above the list is broken, and the text following the chunk becomes embedded in a weird environment (something like the output formatting).
Anyone know if this can be done?
Are you looking for that?
(Save the following code as Rmd file)
---
title: "Untitled"
output: html_document
---
1. Something about some code - you could try this_fun.
1. A more complicated way is to do
```{r, eval = FALSE}
a <- function() { # whole chunk indented by 4!
return(2)
}
print(a())
```
And that may suit your use case
1. Skip it all together
It look like that:

R Markdown – a concise way to print all code snippets used in the document

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.

Is there a way to prevent line break in the HTML when results='hide' and echo=FALSE?

In R, using knitr, is there a way to prevent line breaks in the HTML when results='hide' and echo=FALSE?
In this case:
First I do this,
```{r results='hide', echo=FALSE}
x=4;x
```
then I do that.
I get:
First I do this,
then I do that.
with both a break and an extra line between.
I'd like to get:
First I do this, then I do that.
instead.
Generally speaking, I'd like for code chunks to not insert new lines so that markdown is free to eat the one after the first line of text.
Thanks,
I assume you're creating an HTML document from an R Markdown document. In that case, you can use the inline R code capability offered by knitr by using the ` characters starting with the letter r.
Example:
In your R Markdown, write:
First I do this,`r x=4` then I do that. I can call x by doing `r x`.
And as output, you get:
First I do this, then I do that. I can call x by doing 4.
Note that in my example, I evaluated the variable x, but if you do not want to evaluate it, you do not have to. The variable x should still be assigned a value of 4 from the
`r x=4`
part of the R Markdown.
This is Inline R Code, and is documented here under the section "Inline R Code".
EDIT:
Note that Inline R Code has properties that are analogous to "echo=FALSE". And if you want to hide the results from inline R code, you can use base R functions to hide the output. See this question.
Try something like:
``` {r , results="asis", echo=F, eval=T}
if(showMe){
cat("printed")
} else {
cat("<!-- no break line -->")
}
```

Resources