问题描述
我遇到了以下问题。为了使用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(""))," ")
```
`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.png
与ex1.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")
```
\\
'
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)
}