【问题标题】:I want to write Rmarkdown code with Rmarkdown我想用 Rmarkdown 写 Rmarkdown 代码
【发布时间】:2020-10-01 11:41:11
【问题描述】:

我遇到了以下问题。为了使用 Rexams 自动生成问题集,我想从数据库中读取问题,然后将它们解析为 Rexams 模板,然后生成另一个降价文件,该文件可能包含 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) )

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

```{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) 
```

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

【问题讨论】:

  • 很难理解,尤其是我不知道 Rexams 模板的外观等。您能否尝试添加一个带有一个问题的完整可重现示例。
  • 谢谢,我发布了更多关于我正在使用的较短版本代码的问题的详细信息。
  • 我认为使用writeLines() 而不是cat() 会是更简单的解决方案吗?此外,您可能有兴趣查看 R-Forge 论坛上的讨论:r-forge.r-project.org/forum/… 也许您可以尝试使该策略适应您的数据格式?如果您仍然遇到问题或有疑问,请修改您的问题,我会尝试看看。
  • 谢谢,writeLines 并删除块选项 results="asis" 并添加 comments=NA 成功了,现在一切都在 write_supplement 块中正确转义,现在从数据库自动生成考试包括补充作品。

标签: r-markdown markdown knitr r-exams


【解决方案1】:

没有统一的功能,因为跨数据框、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 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)
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-12-08
    • 1970-01-01
    • 1970-01-01
    • 2017-07-07
    • 1970-01-01
    • 1970-01-01
    • 2021-12-03
    • 2019-04-13
    相关资源
    最近更新 更多