透明地随机化 rmarkdown 中的项目

Randomize items in rmarkdown transparently

我有以下 rmarkdown 文档:

---
title: "Untitled"
output: pdf_document
date: '2022-04-28'
---

```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
```

1. This is the first outer item.
    (a) A
    (b) B
2. This is the second outer item.
    (a) C
    (b) D
3. This is the third outer item.
    (a) E
    (b) F

我想以两种方式同时随机洗牌这个列表:在内部列表内部和外部列表。说,我想得到类似下面的东西:

1. This is the second outer item. 
    (a) D 
    (b) A 
2. This is the first outer item. 
    (a) B 
    (b) A 
3. This is the third outer item. 
    (a) F 
    (b) E 

我知道我可以通过使用字符串编程创建 rmarkdown 代码来实现这一点。所以,我的问题是:是否可以通过编写文档的文本来实现目标而不必求助于字符串编程?原因是我希望在编写文档时能清楚地看到文档的图片,而不是将文档的文本埋在代码中。 (我知道有些编程是不可避免的。)

部分解决方案是使用乳胶。下面显示了一个随机答案的示例。但我也无法随机化问题。也许深入研究手册可以提出解决方案。

---
title: "List Randomize"
header-includes:
   - \usepackage{randomlist}
output: pdf_document
---

## Test randomize

Eine Liste, randomisiert:

\begin{enumerate}
\item Question 1
  \RandomEnumerateList{
  answer1}{
  answer2}{
  answer3}
\item Question 2
  \RandomItemizeList{
  answer1}{
  answer2}{
  answer3}
\end{enumerate}

Package randomlist: https://ctan.joethei.xyz/macros/generic/randomlist/randomlist.pdf

这是我迄今为止取得的最好成绩:

---
title: "Untitled"
output: pdf_document
date: '2022-04-28'
---

```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
library(tidyverse)
```

```{r include=FALSE}
questions <- list(
  question1 = list(
    enun = "This is the first outer item.",
    ans1 = "A.",
    ans2 = "B.",
    ans3 = "X.",
    ans4 = "Y."
  ),
  question2 = list(
    enun = "This is the second outer item.",
    ans1 = "C.",
    ans2 = "D."
  ),
    question3 = list(
    enun = "This is the thrid outer item.",
    ans1 = "E.",
    ans2 = "F."
  )
)
```

```{r echo=FALSE, results='asis'}
qexpand <- function(x)
{
  s1 <- str_c("1. ", x[[1]])
  s2 <- map_chr(sample(2:length(x)), ~ str_c( "\n    (a) ", x[[.x]])) %>% 
        str_c(collapse = " ")
  
  str_c(s1, s2)
}

scr <- map(questions[c(3,1,2)], qexpand)

res = knitr::knit_child(text = scr, quiet = TRUE, )

cat(res, sep="\n")
```

我会按如下方式进行:像上面那样编写文本,然后使用一个函数将其转换为类似于列表列表的结构。然后随机化列表列表,并转换回文本。不要忘记保存答案!这是第一次转换的示例:

questions <- "
1. This is the first outer item.
    (a) A
    (b) B
2. This is the second outer item.
    (a) C
    (b) D
3. This is the third outer item.
    (a) E
    (b) F
"

toListOfLists <- function(text) {
  text <- unlist(strsplit(text, "\n"))
  # These regular expressions match the first line of a question
  # or an answer.  \1 will be the text.
  qreg <- "^[[:digit:]]+[.](.*)"
  areg <- "^[[:space:]]*[(][[:alpha:]][)](.*)"
 
  qstart <- grep(qreg, text)
  astart <- grep(areg, text)
  class <- rep("", length(text))
  class[qstart] <- "q"
  class[astart] <- "a"
  
  result <- list()
  for (i in seq_along(qstart)) {
    line <- qstart[i]
    question <- sub(qreg, "\1", text[line])
    line <- line + 1
    while (line < length(text) & class[line] == "") {
      question <- paste(question, text[line], sep="\n")
      line <- line + 1
    }
    this_astart <- astart[astart >= line]
    if (line < max(qstart))
      this_astart <- this_astart[this_astart < min(qstart[qstart > line])]
    answers <- list()
    for (j in seq_along(this_astart)) {
      line <- this_astart[j]
      answers[[j]] <- sub(areg, "\1", text[line])
      line <- line + 1
      while (line < length(text) & class[line] == "")
        answers[[j]] <- paste(answers[[j]], text[line], sep="\n")
    }
    result[[i]] <- list(question = question, answers = answers)
  }
  result
}

toListOfLists(questions)
#> [[1]]
#> [[1]]$question
#> [1] " This is the first outer item."
#> 
#> [[1]]$answers
#> [[1]]$answers[[1]]
#> [1] " A"
#> 
#> [[1]]$answers[[2]]
#> [1] " B"
#> 
#> 
#> 
#> [[2]]
#> [[2]]$question
#> [1] " This is the second outer item."
#> 
#> [[2]]$answers
#> [[2]]$answers[[1]]
#> [1] " C"
#> 
#> [[2]]$answers[[2]]
#> [1] " D"
#> 
#> 
#> 
#> [[3]]
#> [[3]]$question
#> [1] " This is the third outer item."
#> 
#> [[3]]$answers
#> [[3]]$answers[[1]]
#> [1] " E"
#> 
#> [[3]]$answers[[2]]
#> [1] " F"

reprex package (v2.0.1)

于 2022-04-29 创建

类似于您现有的随机化和转换回文本的解决方案将适用于此结构。