使用data.table制作R-exams试题遇read_metainfo错误求助
解决R-exams中使用data.table时的exsolution错误问题
我最近在用R-exams制作需要data.table的试题时踩了个坑,之前用dplyr做其他试题都顺顺利利的,这次却报错Error in read_metainfo(file) : no exsolution specified——但奇怪的是,直接在全局环境里跑Rmd的代码完全能得到正确结果,这可把我折腾坏了。后来终于搞明白问题出在哪,分享给同样遇到这个问题的朋友:
先看我出问题的Rmd代码片段
```{r data generation, echo = FALSE, results = "hide", cache=FALSE} library(data.table) library(ggplot2) # data.table变量初始化 d <- income <- id <- it <- age <- .N <- NULL n = 100 IT = 40 pension = 1.0 inc1 = runif(n = 1, min = 0.06, max = 0.08) inc2 = -0.0008 alphas = runif(n,min = 0, max = 1) epsilon = 0.2 d = data.table(expand.grid(id=1:n, it = 1:IT)) d[ , alpha := alphas[id]] d[ , age := it + 19] d[ , shock := rnorm(n = .N, sd = epsilon)] d[ , income := exp(alpha + inc1 * age + inc2* age^2 + shock)] d[, alpha := NULL] d[, shock := NULL] # 保存数据 fwrite(d, file = "panel.csv") questions <- solutions <- expl <- list() type <- list() # 问题1 questions[[1]] <- "how many individuals do you observe?" solutions[[1]] <- d[ , max(id)] type[[1]] <- "num" expl[[1]] <- "look at the biggest id entry" # 问题2 questions[[2]] <- "how many time periods?" solutions[[2]] <- d[ , max(it)] expl[[2]] <- "look at the biggest it entry" type[[2]] <- "num"
问题
本题需使用保存于panel.csv的数据集,请右键点击从Moodle下载并保存到本地。我的解答中将该数据集作为对象d使用。
answerlist(unlist(questions), markup = "markdown")
解答
answerlist(unlist(solutions),paste(unlist(expl), ".", sep = ""), markup = "markdown")
元信息
extype: cloze
exsolution: r paste(solutions, collapse = "|")
exclozetype: r paste(type, collapse = "|")
exname: panel
extol: 0.05
### 问题根源 R-exams在解析元信息的时候,有个特殊的机制:它会**先读取元信息块的内容**,如果元信息里的`exsolution`是未执行的R代码(比如我写的`r paste(solutions, collapse = "|")`),它不会主动去执行这段代码,而是把它当成普通文本,所以系统就会报错说“没有指定exsolution”。而我们在全局环境运行时,整个Rmd的代码是按顺序执行的,元信息里的R代码也会被运行,所以能得到正确结果。 ### 解决方法 核心思路就是让元信息里的`exsolution`和`exclozetype`变成已经计算好的字符串,而不是待执行的代码。具体步骤如下: 1. 在**数据生成代码块的末尾**,提前计算好`exsolution`和`exclozetype`的字符串: ```r # 生成元信息需要的字符串(注意要把list转成向量) exsolution_str <- paste(unlist(solutions), collapse = "|") exclozetype_str <- paste(unlist(type), collapse = "|")
- 修改元信息块的内容,直接引用提前计算好的变量:
元信息 =============== extype: cloze exsolution: `r exsolution_str` exclozetype: `r exclozetype_str` exname: panel extol: 0.05
这样修改后,当knitr编译Rmd时,元信息里的r exsolution_str会被替换成实际的计算结果,R-exams就能正确识别到exsolution了。
额外注意点
- 因为
solutions和type都是列表,所以一定要用unlist()把它们转成向量再paste,不然会带list的结构标记,导致exsolution格式错误。 - 关于
data.table的使用其实没问题,和dplyr无关——之前用dplyr顺利只是因为当时的元信息生成方式刚好符合R-exams的要求,这次的问题完全是元信息解析的机制导致的。
内容的提问来源于stack exchange,提问作者Florian Oswald
相关产品推荐
相关产品推荐

