3

动机:我想编写一个界面,在学习者问题/测验中使用 R 包考试中的问题。在 R/exams 中,每个问题都是具有特定结构的 R/Markdown (Rmd) 或 R/LaTeX (Rnw) 文件,指定问题、解决方案和进一步的元信息。问题可以包含使它们动态化的 R 代码,例如,采样数字或某些文本构建块等。因此,工作流程是首先运行问题,或者然后嵌入到合适的输出格式中。knitr::knitutils::Sweave

问题:当我rmarkdown::run("learnr+rexams.Rmd")的学习教程从 Rmd 练习中动态生成问题或测验时,我收到错误:

if (grepl(not_valid_char_regex, label)) { 中的错误:参数长度为零

下面包含一个简单的可重现示例的代码learnr+rexams.Rmd。错误的原因似乎是学习者运行了一个函数,该函数verify_tutorial_chunk_label()试图确保学习者 R 块标签的格式正确。但是,混淆是由 R/exams 包运行的块引起的,不必要地导致上述错误。

解决方法:我可以禁用verify_tutorial_chunk_label()学习者命名空间中的 ,然后一切正常。或者我可以使用 Rnw 代替 Rmd 练习,然后学习者不会与Sweave(). 此外,当我在学习者教程之外运行我的代码时,它可以正常工作。

问题:我可以做一些不那么侵入性的事情来exams与之合作learnr吗?例如,设置一些适当knitr的选项或类似的东西?

示例:learnr+rexams.Rmd这是复制问题的最小学习者教程的来源。请注意,一切都非常简化,仅适用于某些 R/exams 练习,这里使用R/exams 附带的功能练习模板。

---
title: "learnr & R/exams"
output: learnr::tutorial
runtime: shiny_prerendered
---

```{r exams2learnr, include = FALSE}
exams2learnr <- function(file) {
  x <- exams::xexams(file)[[1]][[1]]
  x <- list(text = x$question, type = "learnr_text",
    learnr::answer(x$metainfo$solution, correct = TRUE))
  do.call(learnr::question, x)
}
## assignInNamespace("verify_tutorial_chunk_label", function() return(), ns = "learnr")
```

```{r rfunctions, echo = FALSE, message = FALSE}
exams2learnr("function.Rmd")
```

运行本教程(如上所述)会复制错误。为避免这种情况,我可以取消注释assignInNamespace()呼叫替换"function.Rmd""function.Rnw".

4

1 回答 1

1

问题是当learnr::question()被调用时,knitr 不再能够找到exams2learnr()被调用块的块标签。您可以通过在调用之前设置当前块标签来解决此问题do.call(learnr_question, x)

exams2learnr <- function(file, label = knitr::opts_current$get("label")) {
  force(label)
  x <- exams::xexams(file)[[1]][[1]]
  x <- list(
    text = x$question, 
    type = "learnr_text",
    learnr::answer(x$metainfo$solution, correct = TRUE)
  )
  knitr::opts_current$set(label = label)
  do.call(learnr::question, x)
}

这也允许您根据需要label动态设置,这将成为学习者中问题的 ID。

于 2021-04-14T21:10:35.250 回答