R Markdown - 可变输出名称

58

使用一个R Markdown文件,我想创建不同的可能的输出PDF文档,其中输出文件名应在文档中定义。有没有办法说服Markdown以这种方式操作输出文件名?理想情况下,我想通过r块传递文件名。


你能发一下你的命令吗?你想要动态地命名文件吗?paste0("file_",x,".pdf")? 这里的 x 可以是日期或数据集的名称。 - rmuc8
到目前为止,我一直在使用RStudio,执行knit命令而没有深入了解更多细节。但是我应该更仔细地看一下Ilyas的答案,听起来是一个更清晰的方法。 - Sosel
4个回答

67

您可以使用未记录的knit钩子重新定义RStudio Knit按钮的功能(默认函数称为rmarkdown :: render),以保持使用YAML标头的可重复性。 渲染函数的output_file参数指定文件名,因此通过设置它,您可以覆盖使用与输入文件名相同的前缀的标准行为。

例如,始终输出名为myfile.pdf的文件。

knit: (function(inputFile, encoding) { rmarkdown::render(inputFile, encoding = encoding, output_file = file.path(dirname(inputFile), 'myfile.pdf')) })

这个函数可以是一个匿名的一行代码或者从一个包中导入,如这里所示并使用slidify

你可以设置自己的YAML头信息(我不知道这是否被普遍建议),可以通过rmarkdown::metadata$newheader进行访问,但我认为这种类型的函数内部似乎不可用。

至于从R块中传递文件名...如果您是指YAML头下面的代码块,根据我的经验,我认为这是不可能的(?)。头可以包含内联R命令(单引号括起来的,以r开头),但似乎不适用于这种钩子函数。

相关


rmarkdown::metadata$title <- "我的标题"中的错误: 未找到“rmarkdown”对象。 - jzadra
1
@yihuixie,我可以这样将params$whatever传递到输出文件名中吗?我的markdown使用params$data来获取相关的数据文件,但是在你的一行代码中似乎不起作用--“params$data未找到”。我可以通过脚本传递任何我想要的内容,例如rmarkdown::render(params=list(data="Oct2017data"),output_file="Oct2017_analysis.html"),但显然我只想输入一次。 - StasK
1
@louis-maddox 关于从R块中传递文件名...如果您指的是YAML头下面的代码块,根据我的经验,我认为这不可能(?). 这种情况仍然存在吗?非常感谢! - zoowalk
@zoowalk 同样的问题。 顺便问一下,你找到什么了吗? - MJimitater

35

这基本上就是我所做的:

rmarkdown::render('my_markdown_report.Rmd',
                  output_file = paste('report.', Sys.Date(), 
                                      '.pdf', sep=''))

我有三个脚本 - 一个用于提取数据并进行处理,第二个为报告创建图表和表格。第三个根据Markdown文件创建报告。您在上面看到的代码是第三个脚本的一部分。


到目前为止,我只使用RStudio的knit命令来编译一些Markdown文件。如果我理解正确,您使用R命令创建实际的Markdown文件,甚至使用R命令控制Markdown的编织?迄今为止,我还不知道这种方法,但我会仔细看看。到目前为止,我也在第一个脚本中准备数据并处理它,但在第二步时,我手动创建了一个Markdown文件,将各种数据源放入某个报告中。 - Sosel
是的,Markdown文件是独立的脚本,它可以读取数据、图表和表格。它可以从外部脚本调用,你也可以在Rstudio中启动/执行它,并创建同名文件。但我会从单独的脚本中调用它,在rmarkdown创建pdf结果文件后,将其复制到不同的位置。 - ilya

18

我在没有完全理解如何工作的情况下玩了一下Knitr-hook,并遇到了一个丑陋的解决方法。下面的代码似乎能做到这一点。 如果有人能解释为什么它起作用和/或是否可以写得更少丑陋,那就太好了。

目前我失去了闪亮的输入界面,但相信稍后甚至可以添加。好处是 R-Studio Knit 按钮仍然可以使用。

请注意,副标题和文件名都是:This Works!,即使带有空格和感叹号。该文件保存为 This Works!.pdf

通过将文本分配给对象 pSubTitle 来设置文件名和副标题。 请注意,params 仍然在 YAML 中,但由于在 Knitr-hook 中进行了分配,所以不会导致闪亮的弹出窗口。

输入图像描述的位置

---
params: 
  sub_title:
    input: text
    label: Sub Title
    value: 'my_Sub_Title_and_File_Name'
title    : "Parameterized_Title_and_output_file"
subtitle : "`r params$sub_title`"
output:
  pdf_document:
    keep_tex: false
knit: (
  function(inputFile, encoding) { 
  
    pSubTitle <- 'This Works!'
  
    rmarkdown::render( 
      input       = inputFile, 
      encoding    = encoding, 
      params      = list(sub_title = pSubTitle),      
      output_file = pSubTitle) })
---

```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
```

## R Markdown

This is an R Markdown document. ....

0

我目前解决这个问题和类似问题的方案是通过两个脚本:

  1. 脚本1:“xxx.md”文件具有灵活的yaml头,类似于Floris Padt的。该头允许您生成具有指定标题、日期和其他功能的灵活pdf文件,如果更改参数。但是,它无法在呈现时指定灵活的pdf名称。
---
params: 
    feature_input: "XXXA"
    date: "08/18/2022"
title: "`Test For `r params$feature_input``"
author: "You Name"
date: "`r params$date`"
output: 
  pdf_document:

---

```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
```

## R Markdown and data process

```
#Get parameter from yaml head
input_para <- params$feature_input
input_para
```


第二个脚本: "YYY.R",它在 xxx.md 文件中指定了 params,并在渲染时通过 output_file 指定了 pdf 文件名。
featureNames <- c("aaa", "bbb", "ccc")
setwd("path to xxx.md")
for (currentFeature in featureNames) {
  rmarkdown::render("xxx.Rmd", 
                    params = list(feature_input = currentFeature,
                                  date = Sys.Date()),
                    output_file=paste0("output/",currentFeature))
}
  1. 您可以在 yyy.R 文件中更新 featureNames,并运行 yyy.R 以获得对 xxx.md 文件最灵活的使用。

此解决方案使您能够:

  1. 更新 yaml 头参数,
  2. 在您的 .md 代码块中应用更新的 yaml 参数,
  3. 并以特定且灵活的名称保存您的 pdf。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接