问题
For teaching purposes, I would like to purl
the chunks of my .Rnw
file into separate files. This answer explains how to do it:
How to purl each chunks in .Rmd file to multiple .R files using Knitr
BUT the method does not preserve the chunk options. Since the chunks I have produce plots, it's important to preserve the fig.width
and fig.height
options. Ideally I would like a chunk that looks like this:
<<plot, fig.width = 3, fig.height = 5, outwidth = '.75\\textwidth'>>=
plot (1,1)
@
to become a file named plot.R
that looks like this:
#+ fig.width = 3, fig.height = 5
plot (1,1)
That is, turn the chunk options fig.width
and fig.height
into a format that will be recognized by spin()
, as purl()
does, and get rid of the chunk options that are irrelevant, or create problems for spin()
into Word, such as out.width
. All in the spirit of creating code files that are user-friendly.
回答1:
Since the answer you refer to doesn't copy the header line from the results of purl
, you lose everything besides the chunk name. While you could adapt it to paste in the headers, it's actually not hard to build a function to parse the output of purl
—much easier than trying to parse a Rmd
or Rnw
document, anyway, and easier than sorting out exactly how knitr
does so.
purl_chunks <- function(input_file){
purled <- knitr::purl(input_file) # purl original file; save name to variable
lines <- readLines(purled) # read purled file into a character vector of lines
starts <- grep('^## ----.*-+', lines) # use grep to find header row indices
stops <- c(starts[-1] - 1L, length(lines)) # end row indices
# extract chunk names from headers
names <- sub('^## ----([^-]([^,=]*[^,=-])*)[,-][^=].*', '\\1', lines[starts])
names <- ifelse(names == lines[starts], '', paste0('_', names)) # clean if no chunk name
# make nice file names with chunk number and name (if exists)
file_names <- paste0('chunk_', seq_along(starts), names, '.R')
for(chunk in seq_along(starts)){ # loop over header rows
# save the lines in the chunk to a file
writeLines(lines[starts[chunk]:stops[chunk]], con = file_names[chunk])
}
unlink(purled) # delete purled file of entire document
}
A couple notes:
- While the regex works for what I've thrown at it, it may yet be fallible. Tested:
- no chunk name
- no name but chunk settings
- name with hyphens
- single character names
- names with spaces, including after (before the comma/brace)
- As
.Rnw
and.Rmd
files bothpurl
the same, it works for either. - It uses the default setting (
1L
) forpurl
'sdocumentation
parameter.0L
wouldn't have chunk headers and is thus pointless here anyway, but it would handle2L
(which would include text chunks asroxygen
comments) stupidly. It could be rebuilt for such, though, if you wanted text chunks with the following code chunk. - While the output header lines of
purl
don't look exactly like your example above (they start with## ----
and are filled with hyphens), theyspin
properly; results obey chunk options.
来源:https://stackoverflow.com/questions/35855837/with-knitr-preserve-chunk-options-when-purling-chunks-into-separate-files