You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

动态生成section时read_metainfo读取含Sexpr的.Rnw文件报错问题

问题:使用read_metainfo()读取含\Sexpr的\exsolution时出错/报警告

问题描述

我想通过exams2moodle()的stitle参数动态生成section,不用.Rnw文件里的\exsection,要求stitle结合目录结构和.Rnw中的exname值。但用read_metainfo()读取exname时,只要.Rnw的\exsolution里包含\Sexpr就会报错;更新exams包后虽然程序不会终止,但仍会弹出警告。

附foo.Rnw内容:

<<echo=FALSE, results=hide>>=
solution <- 10
@
\exname{foo}
\exsection{bar}
\extype{num}
\exsolution{\Sexpr{solution}}
\begin{question}
  Foo text...
\end{question}

原因分析

read_metainfo()解析\exsolution时,默认会调用string2num()尝试把内容转成数值,但\Sexpr{solution}是未编译的R表达式占位符,没法直接转成有效数值,所以触发了类型转换错误/警告。更新包后程序不终止,说明官方优化了错误处理逻辑,但警告还是会存在。

解决方法

方法1:关闭元信息自动解析(快速规避警告)

调用read_metainfo()时加parse = FALSE参数,跳过对元信息的自动解析,这样就不会尝试转换exsolution为数值,能正常读取exname:

meta <- read_metainfo("foo.Rnw", parse = FALSE)
exname_val <- meta$exname

拿到exname_val后,就可以结合目录结构生成stitle,再传入exams2moodle()。

方法2:预编译.Rnw后读取元信息

先用knit()编译.Rnw生成临时.tex文件,此时\Sexpr{solution}会被替换成实际数值,再读取编译后的文件元信息就不会有转换问题:

library(knitr)
knit("foo.Rnw", output = "foo_temp.tex")
meta <- read_metainfo("foo_temp.tex")
exname_val <- meta$exname
# 用完临时文件可删除
file.remove("foo_temp.tex")

方法3:正则直接提取exname(轻量方案)

如果只需要exname,可以直接读.Rnw文本,用正则表达式匹配提取,完全绕开read_metainfo()的解析逻辑:

rnw_content <- readLines("foo.Rnw")
exname_match <- grep("\\\\exname\\{(.*)\\}", rnw_content, value = TRUE)
exname_val <- sub("\\\\exname\\{(.*)\\}", "\\1", exname_match)

补充说明

更新exams包后程序不再终止,说明致命错误已被修复,但转换警告还会存在,上面的三种方法都能消除警告并顺利拿到exname。

内容的提问来源于stack exchange,提问作者uzsolt

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 09:10:36