Search code examples
r-exams

How to change the correct answer of a question and replicate exams from scratch when exshuffle is on (package 'exams')?


I have the following question, where the argument of \exsolution is {0010} but it should be {1000}

\begin{question}
What is the capital of Italy

\begin{answerlist}
  \item Rome
  \item Paris
  \item Vienna
  \item Madrid
\end{answerlist}
\end{question}
\extype{schoice}
\exsolution{0010}
\exshuffle{4}

I have corrected the error and re-run the processes of creating and grading exams from scratch using the same seed. Unfortunately, the sequence of answers in this question changes (note \exshuffle{4}), so the grades assigned to this particular question are wrong. All other questions are OK.


Solution

  • Due to the way that exshuffle is implemented it is not easy to just change the {answerlist} and/or exsolution and get the right resulting exam.

    Instead I would recommend to go through the meta-information and fix it there. I presume that you are generating the exams with exams2nops() and have stored the RDS with the metainformation, right? I will produce such a file via:

    set.seed(1)
    exams2nops(c("capitals.Rnw", "italy.Rnw", "switzerland.Rnw"), n = 5, dir = ".")
    

    Thus, there are five exams with 3 exercises each with your problematic exercise italy.Rnw in second place. The metainformation is stored in metainfo.rds which we can read again via

    x <- readRDS("metainfo.rds")
    

    Now x is a list of 5 elements (exams), each of which has 3 elements (exercises), which have elements question, questionlist, solution, solutionlist, metainfo, and supplements. Here, we need to inspect the questionlist in order to fix the metainfo$solution. Currently, Vienna is marked as being correct:

    x[[1]][[2]]$questionlist
    ## [1] "Madrid" "Vienna" "Rome"   "Paris" 
    x[[1]][[2]]$metainfo$solution
    ## [1] FALSE  TRUE FALSE FALSE
    

    However, it should be Rome:

    x[[1]][[2]]$questionlist == "Rome"
    ## [1] FALSE FALSE  TRUE FALSE
    

    So we can loop through this and save the result. Just to be safe, we also store the original RDS file:

    x <- readRDS("metainfo.rds")
    file.copy("metainfo.rds", "metainfo-orig.rds")
    for(i in seq_along(x)) {
      x[[i]][[2]]$metainfo$solution <- x[[i]][[2]]$questionlist == "Rome"
    }
    saveRDS(x, "metainfo.rds")
    

    Final remark: There is also an element metainfo$string that is used when extracting exams_metainfo(). If we wanted to use that, we would need to fix the $string as well. But for nops_eval() it is sufficient to fix the $solution.