我想用 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("")), " ")
```
`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.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)
}
我运行陷入了下面的问题。为了使用 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("")), " ")
```
`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.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)
}