我想用Rmarkdown编写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) )

,但这不会在生成的markdown文件中产生所需的输出。如下所示(我退出了最后一个关闭代码,否则它也不会显示在这里

```{r,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,"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模板用作shousl包含不同练习的markdown文件的模板。

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


quizzes <- tribble(
  ~question,"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,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,results='hide'} \n " )
write_chunk2 <- c("   include_supplement('")
write_chunk3 <- c(paste0(img1,",recursive = TRUE) \n" ))
write_chunk4 <- c("```")

```

```{r write_supplement,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,comment="",results="asis"}

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


```

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


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


Solution
========

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

Meta-@R_847_4045@ion
================

extype: mchoice 

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

exname: `r exname` 
      

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

```{r,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

我将该帖子中的代码改编为data2rmd()函数,该函数可以应用于您问题中的quizzes标题。它假定总是有两个答案选项,然后您可以执行以下操作:

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