Kevin Trutmann
Kevin Trutmann

Reputation: 38

Using purl to source a .Rmd file from within a Rnw file

I have done some analysis in a .Rmd file. I now want to use some objects that are created in this file in a report that I'm writing up as a .Rnw file. Since switching from Sweave to knittr as the weaving engine the following happens:

If i run the line purl(input = 'myfile.Rmd', output = 'myfile.R') in the console, I get an .R file that only contains the R chunks from the .Rmd file. That is what I want. If I put this line into the .Rnw file and knit it (the .Rnw file, that is) however, I do end up with a myfile.R and no errors, but it is completely empty (except for one linebreak for some reason).

I have also tried to put knitr::opts_chunk$set(purl = TRUE) and knit_hooks$set(purl = hook_purl) in the .Rmd file and then use knit() instead of purl() in my .Rnw file, but the result is the same.

The following is a small example:

test.Rnw

\documentclass{article}

\begin{document}

<<test>>=
  library(knitr)
  purl(input = 'test.Rmd', output = 'test.R')
@

\end{document}

test.Rmd

```{r}
answer <- 42
```

Expected Output:

## ------------------------------------------------------------------------
answer <- 42

Actual output:



Does anyone have experience with this? Is this a bug or am I missing something? Thank you for your help!

Upvotes: 1

Views: 508

Answers (2)

Yihui Xie
Yihui Xie

Reputation: 30114

@Cl.'s conjecture was correct. The function knitr::knit() introduces a lot of side-effects, including setting the parsing patterns. In this case, I'd strongly recommend that you run purl() in a separate R session. One way to do it is to change

purl(input = 'test.Rmd', output = 'test.R')

to

xfun::Rscript_call(purl, list(input = 'test.Rmd', output = 'test.R'))

This makes sure purl() is called in a new R session that is (pretty much) independent of the current R session, so the parsing patterns set in the current R session will not affect the new R session's knitr::knit() call.

Upvotes: 3

CL.
CL.

Reputation: 14957

According to ?purl:

knitr will try to decide the pattern list based on the filename extension of the input document, e.g. Rnw files use the list apat$rnw, tex uses the list apat$tex, brew uses apat$brew and HTML files use apat$html

But apparently, this is not the whole story. Note that purl essentially is just a wrapper to knit. My conjecture is, while the RNW document is being knitted, there are some global options set that make knit just look for RNW-like patterns, even if you're purling an RMD file from within the RNW document.

To fix this, explicitly set up Markdown patterns by calling pat_md() before purl(). Afterwards, restore the previous patterns in order to not interfere with the remaining parts of the RNW document.

\documentclass{article}

\begin{document}

<<test>>=
  library(knitr)
  opat <- knit_patterns$get()
  pat_md()
  purl(input = 'test.Rmd', output = 'test.R')
  knit_patterns$set(opat)
@

\end{document}

Upvotes: 2

Related Questions