RMarkdown渲染到包含子块的Notebook

时间:2017-12-20 02:35:20

标签: r knitr r-markdown knitr-spin

我正在尝试将一个Rmd文档(包含对各种“子”文件的引用)呈现给没有这些依赖项的自包含 R笔记本。

目前,.Rmd代码块位于多个.R,.py和.sql文件中,并在报告中使用

引用。
```{r extraction, include=FALSE, cache=FALSE}
knitr::read_chunk("myscript.R")
```

接着是

```{r chunk_from_myscript}
```

记录在案here

我这样做是为了避免代码重复并允许单独运行源文件,但这些代码块只能通过调用knitrenderread_chunk中执行({{{}运行1}}并且代码块可用。)

有没有办法剥离Rmd(编织之前) 只是填充了这些块?

此功能

rmarkdown::render("report.Rmd", clean = FALSE)

几乎到达那里,因为它在删除extraction并填充chunk_from_myscript时留下了markdown文件,但是因为这些文件是直接降价,所以这些块不再可执行且缺少块选项。它显然也不包括运行生成的笔记本所需的eval=TRUE, echo=FALSE块。

我也看了knitr::spin但是这意味着将报告的内容传播到每个源文件,并不是非常理想。

Reprex

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
```

2 个答案:

答案 0 :(得分:1)

完成reprex我现在更好地了解您要解决的问题。您可以knit进入 output.Rmd ,将您的报告和脚本合并到一个降价文件中。

我没有使用knitr::read_chunk,而是将knitr::spin cat asis输入到另一个.Rmd文件中。另请注意params$final标记,以便在设置为TRUE时允许呈现最终文档,或者默认情况下允许knit为中间.Rmd FALSE

report.Rmd

---
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")

output.Rmd

---
title: "Report"
---

Some documentation

```{r chunk_from_myscript, echo=TRUE}
sessionInfo() 
```

使用辅助output.Rmd,您可以继续使用下面的原始回复呈现给html_notebook,以便可以共享文档而无需重新生成但仍包含源R降价文件。

要从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将在编辑窗格中可见。

答案 1 :(得分:0)

由于knitr::knitrmarkdown::render似乎都不适合渲染 R降价,我通过动态地将块文本插入到每个空块中,设法解决了这个问题。并将其写入新文件:

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块 这一步中的任何块。