将变量替换为源代码块中的相应值

时间:2017-04-29 18:39:25

标签: r knitr r-markdown

我想在R Markdown输出中显示参数值而不是params$...。例如,下面的第一个代码块在输出中显示params$file,但我想用samples.txt替换它。我尝试使用message添加第二个块,但是输出一个白色代码块,我喜欢像所有其他R代码块一样的灰色背景。

---
output: html_document
params:
   file: samples.txt
---

```{r read, message=FALSE, collapse=TRUE, comment=""}
x <- read_tsv(params$file)
x
```
This just needs a gray background
```{r print, echo=2, collapse=TRUE, comment=""}
message('x <- read_tsv("', params$file, '")')
x
```

1 个答案:

答案 0 :(得分:4)

您可以修改来源hook。立即按照您的需求量身定制解决方案。对于更通用的方法,它会替换params中的所有元素,向下滚动。

---
output:
  pdf_document: default
  html_document: default
params:
  file: samples.txt
---


```{r, include=FALSE}
library(knitr)
library(stringr)
default_source_hook <- knit_hooks$get('source')

knit_hooks$set(source = function(x, options) {
  x <- str_replace_all(x, pattern = 'params\\$file', paste0("'",params$file,"'"))
  default_source_hook(x, options)
})
```

```{r print, echo=T, comment="", eval = T}
print(params$file)
```

首先,我们保存将根据输出文件类型(render_htmlrender_latex等)使用的默认挂钩。然后我们更改源钩子:我们用它的值替换所有出现的params$file,然后将源代码抛回到我们之前保存的默认钩子中。

在这种情况下,结果如下:

enter image description here

这种魔法有效,因为我们只修改将要打印的源代码,而不是正在评估的源代码!

更新:更通用的方法

我玩了一些你的例子并创建了一个更通用的钩子。它应该替换代码块中params$...形式的所有元素。它甚至会检查值的类型,如果是字符值,则会添加引号。

检查以下MRE:

---
output:
  pdf_document: default
  html_document: default
params:
  file: samples.csv
  age: 28
  awesome: true
  34: badname
  _x: badname
---


```{r, include=FALSE}
library(knitr)
library(gsubfn)

default_source_hook <- knit_hooks$get('source')

knit_hooks$set(source = function(x, options) {
  x <- gsubfn(x = x, pattern = "params\\$`?([\\w_]+)`?", function(y) {
    y <- get(y, params)
    ifelse(is.character(y), paste0("'", y, "'"), y)
  })
  default_source_hook(x, options)
})
```

```{r print, echo=T, comment="", eval = T}
file <- params$file
age  <- params$age
awsm <- params$awesome
# dont name your variables like that! works though...
badexmpls <- c(params$`34`, params$`_x`)
```

我们使用gsubfn()。此函数允许我们使用替换属性的函数(通用gsub中不可能)。此函数采用找到的元素,但是,由于正则表达式只有$之后的部分。所以在这个块中,y等于fileageawesome

enter image description here

相关问题