Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Putting function definition after call in R knitr

Quick, and probably stupid, question: in a R markdown/knitr document, is it possible to put a function definition at the end of the doc (e.g. in an Appendix) after the function is actually called?

like image 832
Alexandre Halm Avatar asked Sep 21 '15 06:09

Alexandre Halm


People also ask

How do you use the knitr in RStudio?

If you are using RStudio, then the “Knit” button (Ctrl+Shift+K) will render the document and display a preview of it. Note that both methods use the same mechanism; RStudio's “Knit” button calls rmarkdown::render() under the hood.

How can you compile the R markdown document using knitr package?

The usual way to compile an R Markdown document is to click the Knit button as shown in Figure 2.1, and the corresponding keyboard shortcut is Ctrl + Shift + K ( Cmd + Shift + K on macOS). Under the hood, RStudio calls the function rmarkdown::render() to render the document in a new R session.

What is the function of knitr in creating markdown document?

knitr is an engine for dynamic report generation with R. It is a package in the programming language R that enables integration of R code into LaTeX, LyX, HTML, Markdown, AsciiDoc, and reStructuredText documents. The purpose of knitr is to allow reproducible research in R through the means of literate programming.

What does ## do in R markdown?

Text: Also on this page, one can see text sections, for example, one section starts with “## R Markdown” this section will render as text when the PDF of this file is produced and all of the formattings that the user will learn generally applies to this section.


1 Answers

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}
```
like image 55
CL. Avatar answered Nov 10 '22 06:11

CL.