是否有用于模块化报告生成的 \SweaveInput{} 的 R 降价模拟?
Is there a R markdown analog of \SweaveInput{} for modular report generation?
我非常喜欢 Sweave 中的一个功能是可以选择拥有单独的 Sweave 文件的 \SweaveInput{} 以获得更多 "modular" 报告,并且能够注释掉报告中的部分我不想使用单个 #\SweaveInput{part_x}
生成,而不必在整个代码块中添加或注释掉。
最近我决定转向 R Markdown 有多种原因,主要是实用性、报告中的交互式(闪亮)集成选项以及我真的不需要 LaTeX 的大量格式设置选项。
我发现从技术上讲,pandoc 能够通过将多个 Rmd 文件连接成一个 html 输出,但是如果可以从 "master" Rmd 文件中调用此行为,那就太好了。
任何答案,即使只是 "go back to Sweave, it is not possible in Markdown"。
,我们将不胜感激
我正在为 Windows 和 Linux 以及 Rstudio 0.98.1056 和 Rstudio 服务器 0.98.983 使用 R 3.1.1。
在主文档中使用类似这样的内容:
```{r child="CapsuleRInit.Rmd"}
```
```{r child="CapsuleTitle.Rmd", eval=TRUE}
```
```{r child="CapsuleBaseline.Rmd", eval=TRUE}
```
使用eval=FALSE
跳过一个child。
对于RStudio用户:你可以定义一个主文档用于latex输出,但这对RMD文档不起作用,所以你总是要切换到主文档进行处理。请支持我对 RStudio 的功能请求;我已经尝试了两次,但在我看来,使用 child 文档的人太少,无法将其置于优先级列表中。
我不太理解上面答案中的一些术语,但解决方案涉及在 YAML header 中定义自定义 knit: hook。对于多部分文档,这允许您,例如:
- 有一个 'main' 或 'root' Rmarkdown 文件和
output: markdown_document
YAML header
- 在调用
render
之前从 Rmd ⇒ md 渲染所有 child 文档,如果是 time-limiting 则不渲染
- 将多个文件(使用 child 代码块选项)合并为一个文件(例如报告中的章节)
- write
output: html_document
(or other format) YAML headers for this compilation output on the fly, prepending to the markdown effectively write a fresh Rmarkdown file
- ...然后呈现此 Rmarkdown 以获得输出,如果需要,删除过程中的中间文件
以上所有的代码 (dumped here) is described here, a post I wrote after working out the usage of custom knit:
YAML header hooks recently (here)。
上例中的自定义 knit:
函数(即 rmarkdown::render
的替换)是:
(function(inputFile, encoding) {
input.dir <- normalizePath(dirname(inputFile))
rmarkdown::render(input = inputFile, encoding = encoding, quiet=TRUE,
output_file = paste0(input.dir,'/Workbook-tmp.Rmd'))
sink("Workbook-compiled.Rmd")
cat(readLines(headerConn <- file("Workbook-header.yaml")), sep="\n")
close(headerConn)
cat(readLines(rmdConn <- file("Workbook-tmp.Rmd")), sep="\n")
close(rmdConn)
sink()
rmarkdown::render(input = paste0(input.dir,'/Workbook-compiled.Rmd'),
encoding = encoding, output_file = paste0(input.dir,'/../Workbook.html'))
unlink(paste0(input.dir,'/Workbook-tmp.Rmd'))
})
...但都挤在了1行!
'master'/'root'/'control' 文件的其余部分或任何您想调用的文件负责为最终 HTML 输出编写上述 YAML通过一个中间 Rmarkdown 文件,它的第二个代码块通过调用 list.files()
以编程方式附加 child 文档
```{r include=FALSE}
header.input.file <- "Workbook-header.yaml"
header.input.dir <- normalizePath(dirname(header.input.file))
fileConn <- file(header.input.file)
writeLines(c(
"---",
paste0('title: "', rmarkdown::metadata$title,'"'),
"output:",
" html_document:",
" toc: true",
" toc_depth: 3 # defaults to 3 anyway, but just for ease of modification",
" number_sections: TRUE",
paste0(" css: ",paste0(header.input.dir,'/../resources/workbook_style.css')),
' pandoc_args: ["--number-offset=1", "--atx-headers"]',
"---", sep="\n"),
fileConn)
close(fileConn)
```
```{r child = list.files(pattern = 'Notes-.*?\.md')}
# Use file names with strict numeric ordering, e.g. Notes-001-Feb1.md
```
目录结构将包含一个 top-level 文件夹
- 最终输出
Workbook.html
- 一个包含
workbook_style.css
的 resources
子文件夹
- 一个
documents
子文件夹,其中包含所述主文件 "Workbook.Rmd" 以及名为 "Notes-001.Rmd"、"Notes-002.Rmd" 等的文件(以确保 list.files(pattern = "Notes-.*?\.Rmd)
上的文件匹配找到从而在呈现主 Workbook.Rmd
文件时使它们 children 以正确的顺序)
为了获得正确的文件编号,每个组成 "Notes-XXX.Rmd" 文件应包含以下样式的 YAML header:
---
title: "March: Doing x, y, and z"
knit: (function(inputFile, encoding) { input.dir <- normalizePath(dirname(inputFile)); rmarkdown::render(input = inputFile, encoding = encoding, quiet=TRUE)})
output:
md_document:
variant: markdown_github
pandoc_args: "--atx-headers"
---
```{r echo=FALSE, results='asis', comment=''}
cat("##", rmarkdown::metadata$title)
```
Rmarkdown 文档顶部的代码块在评估时将 YAML 标题作为 second-level header 输入。 results='asis'
表示 return 普通 text-string 而不是
[1] "A text string"
您可以在 编织主文件之前编织这些文件中的每一个 - 删除呈现所有 child 文档并仅附加其 [=108= 的要求更容易] 降价输出。
我已经在上面的链接中描述了所有这些,但我认为不留下我的答案的实际代码是不礼貌的。
我不知道 RStudio 功能请求网站的效率如何...就我个人而言,我发现查看这些功能的源代码并不困难,谢天谢地是 open source,并且如果确实存在 不存在 而不是未记录的 inner-workings-informed 功能请求,则其软件开发人员可能更容易采取行动。
我对 Sweave 不熟悉,以上是你的目标吗?如果我理解正确的话,您只想以模块化方式控制文档的包含。 child = list.files()
语句可以解决这个问题:如果不通过文件通配,您可以 straight-up 将文件列为 child = c("file1.md","file2md")
... 并切换该语句以更改 children。您还可以使用 YAML 控制 TRUE/FALSE 开关,因此自定义 header 的存在将设置一些 children 被包含,例如
potentially.absent.variable: TRUE
...在文档上方有一个无声的 include=FALSE
隐藏了第一个块的阴谋:
```{r include=FALSE}
!all(!as.logical(rmarkdown::metadata$potentially.absent.variable)
# ==> FALSE if potentially.absent.variable is absent
# ==> FALSE if anything other than TRUE
# ==> TRUE if TRUE
checkFor <- function(var) {
return !all(!as.logical(rmarkdown::metadata[[var]])
}
```
```{r child = "Optional_file.md", eval = checkFor(potentially.absent.variable)}
```
我非常喜欢 Sweave 中的一个功能是可以选择拥有单独的 Sweave 文件的 \SweaveInput{} 以获得更多 "modular" 报告,并且能够注释掉报告中的部分我不想使用单个 #\SweaveInput{part_x}
生成,而不必在整个代码块中添加或注释掉。
最近我决定转向 R Markdown 有多种原因,主要是实用性、报告中的交互式(闪亮)集成选项以及我真的不需要 LaTeX 的大量格式设置选项。
我发现从技术上讲,pandoc 能够通过将多个 Rmd 文件连接成一个 html 输出,但是如果可以从 "master" Rmd 文件中调用此行为,那就太好了。
任何答案,即使只是 "go back to Sweave, it is not possible in Markdown"。
,我们将不胜感激我正在为 Windows 和 Linux 以及 Rstudio 0.98.1056 和 Rstudio 服务器 0.98.983 使用 R 3.1.1。
在主文档中使用类似这样的内容:
```{r child="CapsuleRInit.Rmd"}
```
```{r child="CapsuleTitle.Rmd", eval=TRUE}
```
```{r child="CapsuleBaseline.Rmd", eval=TRUE}
```
使用eval=FALSE
跳过一个child。
对于RStudio用户:你可以定义一个主文档用于latex输出,但这对RMD文档不起作用,所以你总是要切换到主文档进行处理。请支持我对 RStudio 的功能请求;我已经尝试了两次,但在我看来,使用 child 文档的人太少,无法将其置于优先级列表中。
我不太理解上面答案中的一些术语,但解决方案涉及在 YAML header 中定义自定义 knit: hook。对于多部分文档,这允许您,例如:
- 有一个 'main' 或 'root' Rmarkdown 文件和
output: markdown_document
YAML header - 在调用
render
之前从 Rmd ⇒ md 渲染所有 child 文档,如果是 time-limiting 则不渲染
- 将多个文件(使用 child 代码块选项)合并为一个文件(例如报告中的章节)
- write
output: html_document
(or other format) YAML headers for this compilation output on the fly, prepending to the markdown effectively write a fresh Rmarkdown file- ...然后呈现此 Rmarkdown 以获得输出,如果需要,删除过程中的中间文件
以上所有的代码 (dumped here) is described here, a post I wrote after working out the usage of custom knit:
YAML header hooks recently (here)。
上例中的自定义 knit:
函数(即 rmarkdown::render
的替换)是:
(function(inputFile, encoding) {
input.dir <- normalizePath(dirname(inputFile))
rmarkdown::render(input = inputFile, encoding = encoding, quiet=TRUE,
output_file = paste0(input.dir,'/Workbook-tmp.Rmd'))
sink("Workbook-compiled.Rmd")
cat(readLines(headerConn <- file("Workbook-header.yaml")), sep="\n")
close(headerConn)
cat(readLines(rmdConn <- file("Workbook-tmp.Rmd")), sep="\n")
close(rmdConn)
sink()
rmarkdown::render(input = paste0(input.dir,'/Workbook-compiled.Rmd'),
encoding = encoding, output_file = paste0(input.dir,'/../Workbook.html'))
unlink(paste0(input.dir,'/Workbook-tmp.Rmd'))
})
...但都挤在了1行!
'master'/'root'/'control' 文件的其余部分或任何您想调用的文件负责为最终 HTML 输出编写上述 YAML通过一个中间 Rmarkdown 文件,它的第二个代码块通过调用 list.files()
```{r include=FALSE}
header.input.file <- "Workbook-header.yaml"
header.input.dir <- normalizePath(dirname(header.input.file))
fileConn <- file(header.input.file)
writeLines(c(
"---",
paste0('title: "', rmarkdown::metadata$title,'"'),
"output:",
" html_document:",
" toc: true",
" toc_depth: 3 # defaults to 3 anyway, but just for ease of modification",
" number_sections: TRUE",
paste0(" css: ",paste0(header.input.dir,'/../resources/workbook_style.css')),
' pandoc_args: ["--number-offset=1", "--atx-headers"]',
"---", sep="\n"),
fileConn)
close(fileConn)
```
```{r child = list.files(pattern = 'Notes-.*?\.md')}
# Use file names with strict numeric ordering, e.g. Notes-001-Feb1.md
```
目录结构将包含一个 top-level 文件夹
- 最终输出
Workbook.html
- 一个包含
workbook_style.css
的 - 一个
documents
子文件夹,其中包含所述主文件 "Workbook.Rmd" 以及名为 "Notes-001.Rmd"、"Notes-002.Rmd" 等的文件(以确保list.files(pattern = "Notes-.*?\.Rmd)
上的文件匹配找到从而在呈现主Workbook.Rmd
文件时使它们 children 以正确的顺序)
resources
子文件夹
为了获得正确的文件编号,每个组成 "Notes-XXX.Rmd" 文件应包含以下样式的 YAML header:
---
title: "March: Doing x, y, and z"
knit: (function(inputFile, encoding) { input.dir <- normalizePath(dirname(inputFile)); rmarkdown::render(input = inputFile, encoding = encoding, quiet=TRUE)})
output:
md_document:
variant: markdown_github
pandoc_args: "--atx-headers"
---
```{r echo=FALSE, results='asis', comment=''}
cat("##", rmarkdown::metadata$title)
```
Rmarkdown 文档顶部的代码块在评估时将 YAML 标题作为 second-level header 输入。 results='asis'
表示 return 普通 text-string 而不是
[1] "A text string"
您可以在 编织主文件之前编织这些文件中的每一个 - 删除呈现所有 child 文档并仅附加其 [=108= 的要求更容易] 降价输出。
我已经在上面的链接中描述了所有这些,但我认为不留下我的答案的实际代码是不礼貌的。
我不知道 RStudio 功能请求网站的效率如何...就我个人而言,我发现查看这些功能的源代码并不困难,谢天谢地是 open source,并且如果确实存在 不存在 而不是未记录的 inner-workings-informed 功能请求,则其软件开发人员可能更容易采取行动。
我对 Sweave 不熟悉,以上是你的目标吗?如果我理解正确的话,您只想以模块化方式控制文档的包含。 child = list.files()
语句可以解决这个问题:如果不通过文件通配,您可以 straight-up 将文件列为 child = c("file1.md","file2md")
... 并切换该语句以更改 children。您还可以使用 YAML 控制 TRUE/FALSE 开关,因此自定义 header 的存在将设置一些 children 被包含,例如
potentially.absent.variable: TRUE
...在文档上方有一个无声的 include=FALSE
隐藏了第一个块的阴谋:
```{r include=FALSE}
!all(!as.logical(rmarkdown::metadata$potentially.absent.variable)
# ==> FALSE if potentially.absent.variable is absent
# ==> FALSE if anything other than TRUE
# ==> TRUE if TRUE
checkFor <- function(var) {
return !all(!as.logical(rmarkdown::metadata[[var]])
}
```
```{r child = "Optional_file.md", eval = checkFor(potentially.absent.variable)}
```