我想用 Rmarkdown 写 Rmarkdown 代码

I want to write Rmarkdown code with Rmarkdown

我运行陷入了下面的问题。为了使用 Rexams 自动生成问题集,我想从数据库中读取问题,然后将它们解析为 Rexams 模板,然后生成另一个 markdown 文件,该文件可能包含 R 代码块,然后应该由 Rexams 处理。我尝试了几种获取逐字文本的形式,例如

write_chunk1 <- c("```{r, echo = FALSE, results='hide'} \n " )
write_chunk2 <- c("   include_supplement('UCL-J16-Q13-01.png', recursive = TRUE) \n" )
write_chunk3 <- c("```")

cat(noquote(write_chunk1) )
cat(noquote(write_chunk2) )
cat(noquote(write_chunk3) )

但这不会在生成的降价文件中产生所需的输出。应该是下面的(我把最后一个代码closing 转义了,不然这里也不会显示)

```{r, echo = FALSE, results='hide'} 
include_supplement('UCL-J16-Q13-01.png', recursive = TRUE) 
```

以下文件运行一个循环,获取“测验”数据库并将信息放入 Rexams 模板

library(knitr)
library(rmarkdown)
library(here)
library(exams)
library(dplyr)
library(readxl)



## paths
# file.copy(here("quizzes/input/images","*.png"),to = here("quizzes/output/rmd_question_files/"))

## Data


quizzes <- tribble(
~identifier,  ~question, ~answer1, ~answer2, ~solution1, ~solution2, ~feedback1, ~feedback2, ~image, 
 "Q1", "Is this good",   "yes", "no", 1, 0, "Because it is", "Wrong", "smile.png"
  )


## Loop
for (i in 1:nrow(quizzes)){
  rmarkdown::render(input = here("quizzes/code/", "template_rexams.Rmd"),
                    output_format = "md_document",
                    output_file = paste0(quizzes$Identifier[i], ".Rmd"),
                    output_dir = here("quizzes/output/rmd_question_files/")
  )
}

rexams 模板用作应包含不同练习的降价文件的模板。

---
output: md_document
---
 
```{r echo=FALSE, message=FALSE, warning=FALSE}


quizzes <- tribble(
  ~question, ~answer1, ~answer2, ~solution1, ~solution2, ~feedback1, ~feedback2, ~image, 
  "Is this good",   "yes", "no", 1, 0, "Because it is", "Wrong", "smile.png"
  )

# Read question
question <- quizzes$question[i]

# Create answer lists and solutions with feeback
answers <- c(quizzes$answer1[i], quizzes$answer2[i])

sol <- c(quizzes$solution1[i], quizzes$solution2[i])
sol <- ifelse(sol == 1, TRUE, FALSE)

feedback <- c(quizzes$feedback1[i], quizzes$feedback2[i])

## Get image identifiers
img1 <- quizzes$image

```


```{r get-images, echo=FALSE, message=FALSE, warning=FALSE}
# Define variable containing image locations
img_path <- here::here("quizzes/input/images/")

img1_pt <- ifelse(img1 != "", paste0(img_path, paste0(quizzes$image[i],".png")), "")

img1 <- ifelse(img1 != "", paste0(quizzes$image,".png"), "")


if (!is.na(img1)){
  include_supplement(file = c(img1), dir = img_path, recursive = TRUE)
}

write_chunk1 <- c("{r, echo = FALSE, results='hide'} \n " )
write_chunk2 <- c("   include_supplement('")
write_chunk3 <- c(paste0(img1, ", recursive = TRUE) \n" ))
write_chunk4 <- c("```")

```

```{r write_supplement, echo=FALSE, message=FALSE, warning=FALSE, results="asis"}
cat(noquote(write_chunk1) )
cat(noquote(write_chunk2), noquote(write_chunk3) )
cat(noquote(write_chunk4) )
```


Question
========
**Unit `r unit`.`r nmb`**

`r question`


```{r insert-images, echo=FALSE, message=FALSE, warning=FALSE, comment="", results="asis"}

img1_pr <- ifelse(img1 != "", paste0("![](", paste0(img1, ")")), " ")


```

`r if(!is.na(img1)){noquote(img1_pr)}`


```{r answerlist, echo = FALSE, results = "asis"}
answerlist(answers, markup = "markdown")
```


Solution
========

```{r solutionlist, echo = FALSE, results = "asis"}
answerlist(ifelse(sol == 1, "**True**", "**False**"), markup = "markdown", feedback)
```

Meta-information
================

extype: mchoice 

exsolution: `r mchoice2string(sol, single = FALSE)` 

exname: `r exname` 
      

现在的问题是,这个新的 markdown 文件应该在 markdown 文件的开头包含以下代码块,其中要包含的图像的名称会因练习而改变。

```{r, echo = FALSE, results='hide'} 
include_supplement('smile.png', recursive = TRUE) 
```

我希望这能更好地解释我的问题。我认为我的问题是我不知道如何转义 ``` 以便将其写入文件。

这没有统一的功能,因为跨数据框、CSV 或数据库文件的问题的准确表示通常是多种多样的。但是,我使用的一般方法是使用 %s 字符串占位符为 Rmd(或 Rnw)练习设置一个字符模板,并用数据中的信息填充占位符。最后,我使用 writeLines() 将结果代码写到练习文件中。

R-Forge 上的 R/exams 论坛讨论了处理特定 CSV 文件格式的工作示例,地址为: https://R-Forge.R-project.org/forum/forum.php?thread_id=34046&forum_id=4377&group_id=1337

我将 post 中的代码改编成一个 data2rmd() 函数,可以应用于您问题中的 quizzes tibble。它假定总是恰好有两个答案选项,然后你可以这样做:

data2rmd(quizzes)

它使用 R/Markdown 代码创建一个文件 ex1.Rmd。然后可以使用 exams2html("ex1.Rmd") 或任何其他 exams2xyz() 函数对其进行处理 - 前提是图像文件 smile.pngex1.Rmd.

位于同一文件夹中

函数:

data2rmd <- function(x, ...) {
  ## Rmd exercise template
  rmd <- '
Question
========

%s
%s

Answerlist
----------

* %s
* %s

Solution
========

Answerlist
----------

* %s
* %s

Meta-information
================
exname: %s
extype: schoice
exsolution: %s
'

  ## convenience functions
  include_image <- function(x) {
    if(x == "") return("")  
    rmd <- '```{r, echo = FALSE, results = "hide"}
include_supplement("%s")
```
\
![](%s)'
    sprintf(rmd, x, x)
  }
  
  ## insert data base into template
  nam <- paste0("ex", 1L:nrow(x))
  rmd <- sprintf(rmd,
    x$question,
    sapply(x$image, include_image),
    x$answer1, x$answer2,
    x$feedback1, x$feedback2,
    nam,
    paste0(x$solution1, x$solution2)
  )


  ## write Rmd files
  for(i in 1L:nrow(x)) writeLines(rmd[i], paste0(nam[i], ".Rmd"))
  invisible(rmd)
}