Kevin Arseneau
Kevin Arseneau

Reputation: 6264

When running knit to .Rmd output the chunks are not valid

Problem

When trying to knit an .Rmd containing read_chunk lines from purl scripts into a parent .Rmd, the chunks are not complete and only form code blocks. I want to be able to knit the output file normally.

Code

main.Rmd

---
output: html_document
---

```{r, include=FALSE}
knitr::read_chunk("script_chunk.R")
```

### Print sessionInfo()

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

script_chunk.R

# ---- script_chunk
sessionInfo()

Knitting

When I process this with knit("main.Rmd", "output.Rmd") the following file is generated:

---
output: html_document
---



### Print sessionInfo()


```r
sessionInfo()
```

However, the desired output for the chunk is:

```{r script_chunk}
sessionInfo()
```

When I knit output.Rmd currently, I only get an un-evaluated code block because the chunk is missing the curly braces (and preferably the chunk name).

enter image description here

Workaround

I can use readLines to achieve what I'm after, for example with:

```{r, results='asis', collapse=TRUE, echo=FALSE}
cat("```{r script_chunk}\n")
cat(paste(readLines("script_chunk.R"), "\n", collapse = ""))
cat("```\n")
```

Is there a more elegant way to do this?

Upvotes: 4

Views: 866

Answers (2)

r2evans
r2evans

Reputation: 160437

An alternative I use is with knit_child:

  • main.Rmd

    ---
    output: html_document
    ---
    
    ```{r, include=FALSE}
    out <- knitr::knit_child("script_chunk.Rmd")
    ```
    
    ### Print sessionInfo()
    ```{r, ref.label='script_chunk'}
    paste(out, collapse = "\n")
    ```
    
  • script_chunk.Rmd

    ```{r script_chunk}
    # ---- script_chunk
    sessionInfo()
    ```
    

When compiled:

---
output: html_document
---

### Print sessionInfo()

```r
# ---- script_chunk
sessionInfo()
```

```
## R version 3.3.3 (2017-03-06)
## Platform: x86_64-w64-mingw32/x64 (64-bit)
## Running under: Windows 10 x64 (build 16299)
## ... blah blah blah ...
```

Thoughts:

  1. out is a horrible name for this;
  2. I often use it to iterate a single child document (which handles one "thing") over zero or more things, so out can contain concatenated results of multiple calls to knit_child

Upvotes: 3

Nathan Werth
Nathan Werth

Reputation: 5263

There is a slightly more elegant solution:

# main.Rmd
---
output: html_document
---

### Print sessionInfo()

```{r, results="asis", echo = FALSE}
chunk_lines <- knitr::spin(text = readLines("script_chunk.R"), knit = FALSE)
cat(chunk_lines, sep = "\n")
```

But remember that your output, as far as knitr cares, is plain Markdown. knitr can only output to certain formats: LaTeX, Sweave, HTML, Markdown or Jekyll. While your output file has the .Rmd extension, its contents are plain Markdown because that's the default for R Markdown files.

So be aware that all code chunks you want in the output will have to be written as dynamic output. Which could leave you with obfuscated code in main.Rmd.

Upvotes: 6

Related Questions