Defer Code to End of Document in Knitr

Defer code to END of document in knitr

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 :-)

Use rmarkdown/knitr to hold all code until the end

If I understand correctly what you mean.
You can add a label to your original code chunk and then refer to it using a ref.label property and prevent its further execution with eval=FALSE.

For instance:

 # Header
Bla bla ...
````{r plot1,echo=FALSE}
x = rnorm(100,10,5)
y = rnorm(100,10,5)
plot(x,y)
````

# Appendix

Code chunk:
````{r ref.label="plot1",eval=FALSE}
```

The first chunk is executed (without echo) and shows a figure, the second chunk just echoes the first chunk's source.

Putting function definition after call in R knitr

Is it possible to put a function definition at the end of the document, after the function is actually called?

Technically, no. A function needs to be defined before it is called. However, as the question relates to knitr it should be rephrased:

Is it possible to show a function definition at the end of the document, after the function is actually called?

Yes, and there are several ways to achieve this. Note that options 2 and 3 can be found in Print highlighted source code of a function.

Option 1: Reuse chunks

Define the function before it is used.

```{r definition, echo = FALSE}
myfun <- function(x) {
return(sprintf("You passed me %s", x))
}
```

Use the function:
```{r}
myfun(123)
```

Show the chunk where it was defined:
```{r definition, eval = FALSE}
```

An empty chunk with the same label as another non-empty chunk "inherits" the latter's code. This is described in How to reuse chunks.
The code inside the chunk definition is hidden at first (echo = FALSE). Later, when the code is to be printed, use eval = FALSE in order to avoid evaluating the code again.

This option is handy when the function is defined in a separate chunk.

Option 2: Simple print

This is the simplest option but the output won't have syntax highlighting. Just define the function in a hidden chunk, use it and print the function definition later:

Define the function *before* it is used.

```{r definition, echo = FALSE}
myfun <- function(x) {
return(sprintf("You passed me %s", x))
}
```

Use the function:
```{r}
myfun(123)
```

```{r}
myfun
```

Option 3: Generate a chunk containing the function definition

This option is described on Yihui's website. It uses the function insert_fun to generate a chunk that contains the function definition.

insert_fun = function(name) {
read_chunk(lines = capture.output(dump(name, '')), labels = paste(name, 'source', sep = '-'))
}

This approach is very flexible because it doesn't matter if the function is defined in a separate chunk or in a file that is sourced.

insert_fun takes the name of an function (as character) and creates a chunk labelled functionname-source:

Define the function *before* it is used.

```{r definition, echo = FALSE}

# Define your function.
myfun <- function(x) {
return(sprintf("You passed me %s", x))
}

library(knitr)

# Define insert_fun.
insert_fun = function(name) {
read_chunk(lines = capture.output(dump(name, '')), labels = paste(name, 'source', sep = '-'))
}

insert_fun("myfun") # creates a chunk labelled "myfun-source"
```

Use the function:
```{r}
myfun(123)
```

```{r myfun-source, eval = FALSE}
```

How to show the whole result of a knitted chunk at the end of it

Use collapse=TRUE, documented here: https://yihui.org/knitr/options/#code-evaluation.

---
title: hello
---

```{r blockname}
message("hello")
message("world")
```

rmarkdown chunk without collapse

---
title: hello
---

```{r blockname, collapse = TRUE}
message("hello")
message("world")
```

rmarkdown chunk with collapse

Since you need to change the way R shows things (output after a command), then we need to borrow from a previous answer of mine:

---
title: hello
---

```{r blockname, echo = FALSE, include = FALSE}
message("hello")
message("world")
```

```{r showblockname, ref.label='blockname', eval=FALSE}
```

```{r blockname, echo=FALSE, collapse=TRUE}
```

rmarkdown chunk, shifted-output and collapsed

Matching the knitr document environment in a custom engine

It turns out that there is a function in {knitr} precisely for this situation: knitr::knit_global(), which happens to be the environment when evaluating inline code: https://github.com/yihui/knitr/blob/0daf31be36eed8d8ec0ba51eedee909283afc45d/R/hooks.R#L13

knitr::knit_engines$set(flip = 
function(options) {
# pre-process code
code <- gsub("(#+?)", "\\1 (╯°□°)╯︵", options$code)

e <- knitr::knit_global() # <----- SOLUTION ᕕ( ᐛ )ᕗ

OUT <- evaluate::evaluate(code, envir = e)
knitr::engine_output(options, out = OUT)
}
)

tmp <- tempfile(fileext = ".Rmd")
tmpout <- tempfile(fileext = ".md")
txt <- "---\noutput: md_document\n---\n\n```{r}\na <- 'A'\na\n```\n\n```{flip}\nb <- paste(a, 'and B') # FLIPPIN\nb\n```\n\nSponsored by the letters `r try(b)`\n"
cat(txt, file = tmp)

rmarkdown::render(tmp, output_file = tmpout, envir = new.env())
#> processing file: file3b0117b9cb1f.Rmd
#> output file: file3b0117b9cb1f.knit.md
#> /usr/bin/pandoc +RTS -K512m -RTS file3b0117b9cb1f.utf8.md --to markdown_strict --from markdown+autolink_bare_uris+tex_math_single_backslash --output /tmp/Rtmp1KgoUj/file3b01702d22f0.md --standalone
#>
#> Output created: /tmp/Rtmp1KgoUj/file3b01702d22f0.md
cat(readLines(tmp), sep = "\n")
#> ---
#> output: md_document
#> ---
#>
#> ```{r}
#> a <- 'A'
#> a
#> ```
#>
#> ```{flip}
#> b <- paste(a, 'and B') # FLIPPIN
#> b
#> ```
#>
#> Sponsored by the letters `r try(b)`
cat(readLines(tmpout), sep = "\n")
#> a <- 'A'
#> a
#> #> [1] "A"
#>
#> b <- paste(a, 'and B') # (╯°□°)╯︵ FLIPPIN
#> b
#> #> [1] "A and B"
#>
#> Sponsored by the letters A and B

Created on 2020-06-16 by the reprex package (v0.3.0)



Related Topics



Leave a reply



Submit