[英]RMarkdown render to Notebook with child chunks included
我正在寻找一种将Rmd文档(其中包含对各种“子”文件的引用)呈现给不包含这些依赖项的自包含 R Notebook的一种方法。
目前,.Rmd代码块位于整个.R,.py和.sql文件中,并在报告中使用
```{r extraction, include=FALSE, cache=FALSE}
knitr::read_chunk("myscript.R")
```
其次是
```{r chunk_from_myscript}
```
如这里所记载。
我这样做是为了避免代码重复,并允许单独运行源文件,但是这些代码块只能通过调用knit
或render
(在运行read_chunk
并且代码块可用时)才能在read_chunk
中执行。
是否有一种方法可以在仅填充这些块的情况下剥离Rmd(在编织之前)?
该功能
rmarkdown::render("report.Rmd", clean = FALSE)
几乎到达那里了,因为它留下了markdown文件,同时删除了extraction
并填充chunk_from_myscript
但是由于这些文件是直接markdown的,因此这些块不再可执行,并且缺少块选项。 显然,它也不包括运行结果笔记本需要的eval=TRUE, echo=FALSE
块。
我也看过knitr::spin
但这意味着将报告的内容分发到每个源文件中,并且不是很理想。
report.Rmd
---
title: 'Report'
---
```{r read_chunks, include=FALSE, cache=FALSE}
knitr::read_chunk("myscript.R")
```
Some documentation
```{r chunk_from_myscript}
```
Some more documentation
```{r chunk_two_from_myscript, eval=TRUE, echo=FALSE}
```
myscript.R
#' # MyScript
#'
#' This is a valid R source file which is formatted
#' using the `knitr::spin` style comments and code
#' chunks.
#' The file's code can be used in large .Rmd reports by
#' extracting the various chunks using `knitr::read_chunk` or
#' it can be spun into its own small commented .Rmd report
#' using `knitr::spin`
# ---- chunk_from_myscript
sessionInfo()
#' This is the second chunk
# ---- chunk_two_from_myscript
1 + 1
期望的输出
notebook.Rmd
---
title: 'Report'
---
Some documentation
```{r chunk_from_myscript}
sessionInfo()
```
Some more documentation
```{r chunk_two_from_myscript, eval=TRUE, echo=FALSE}
1 + 1
```
现在,通过您的reprex
我可以更好地了解您要解决的问题。 您可以knit
到output.Rmd中,以将报告和脚本合并到单个markdown文件中。
而不是使用的knitr::read_chunk
,我已经阅读knitr::spin
到cat
的asis
输出到另一个.Rmd
文件。 还要注意params$final
标志,当设置为TRUE
时默认呈现最终文档,或者默认情况下允许将knit
到中间.Rmd
为FALSE
。
---
title: "Report"
params:
final: false
---
```{r load_chunk, include=FALSE}
chunk <- knitr::spin(text = readLines("myscript.R"), report = FALSE, knit = params$final)
```
Some documentation
```{r print_chunk, results='asis', echo=FALSE}
cat(chunk, sep = "\n")
```
产生中间文件:
rmarkdown::render("report.Rmd", "output.Rmd")
---
title: "Report"
---
Some documentation
```{r chunk_from_myscript, echo=TRUE}
sessionInfo()
```
使用secondary output.Rmd
,您可以继续下面的原始响应以呈现到html_notebook
以便可以共享文档而无需重新生成,但仍包含源R markdown文件。
要从report.Rmd
渲染最终文档,可以使用:
rmarkdown::render("report.Rmd", params = list(final = TRUE))
您需要在render
语句中包含其他参数。
rmarkdown::render(
input = "output.Rmd",
output_format = "html_notebook",
output_file = "output.nb.html"
)
当您在RStudio中打开.nb.html
文件时,嵌入式.Rmd
将在编辑窗格中可见。
由于knitr::knit
和rmarkdown::render
都不适合渲染为 R markdown,因此我设法通过将块文本动态插入每个空块并将其写入新文件中来解决此问题:
library(magrittr)
library(stringr)
# Find the line numbers of every empty code chunk
get_empty_chunk_line_nums <- function(file_text){
# Create an Nx2 matrix where the rows correspond
# to code chunks and the columns are start/end line nums
mat <- file_text %>%
grep(pattern = "^```") %>%
matrix(ncol = 2, byrow = TRUE)
# Return the chunk line numbers where the end line number
# immediately follows the starting line (ie. chunk is empty)
empty_chunks <- mat[,1] + 1 == mat[,2]
mat[empty_chunks, 1]
}
# Substitute each empty code chunk with the code from `read_chunk`
replace_chunk_code <- function(this_chunk_num) {
this_chunk <- file_text[this_chunk_num]
# Extract the chunk alias
chunk_name <- stringr::str_match(this_chunk, "^```\\{\\w+ (\\w+)")[2]
# Replace the closing "```" with "<chunk code>\n```"
chunk_code <- paste0(knitr:::knit_code$get(chunk_name), collapse = "\n")
file_text[this_chunk_num + 1] %<>% {paste(chunk_code, ., sep = "\n")}
file_text
}
render_to_rmd <- function(input_file, output_file, source_files) {
lapply(source_files, knitr::read_chunk)
file_text <- readLines(input_file)
empty_chunks <- get_empty_chunk_line_nums(file_text)
for (chunk_num in empty_chunks){
file_text <- replace_chunk_code(file_text, chunk_num)
}
writeLines(file_text, output_file)
}
source_files <- c("myscript.R")
render_to_rmd("report.Rmd", "output.Rmd", source_files)
这具有保留块选项以及使用Python和SQL块的额外好处,因为在此步骤中无需评估任何块。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.