【问题标题】:Creation of especialized \Sexpr function version创建专门的 \Sexpr 函数版本
【发布时间】:2020-11-23 23:43:27
【问题描述】:

我正在使用exams 包生成一些考试(工程)。我的源文件是Rnw 格式,所以底层引擎是Sweave。

在 R 端,我正在使用 units 包(检查维度正确性)并且我创建了一个函数(称为 units2tex)将大小从单位转换为 LaTeX 等效值。所以,当我计算一个变量时,我必须为 LaTeX 创建一个副本:

<<>>=
R = set_units(1,ohm)
I = set_units(1,A)
V = R*I

R_tex = units2tex(R)
I_tex = units2tex(I)
#V_tex = units2tex(V)

@

For $R = \Sexpr{R_tex}$, the answer is \Sexpr{units2tex(V)}.

在这两种情况下(打印R 和V)我必须在某处显式调用units2tex 函数。因为有很多步骤和中间时间值,所以要输入很多字(输入更多,错误的地方也更多)。

是否可以通过自动函数调用轻松创建 \Sexpr 版本?

更具体地说:

  • 是否可以创建\SexprT{V} 来像\Sexpr{units2tex(V)} 一样工作?
  • 是否可以创建\SexprT{V,digits=2}(或类似的)来像\Sexpr{units2tex(V,digits=2)}一样工作?

在这两种情况下都不会丢失使用原始\Sexpr。

我目前的选择及其缺点:

  • 显式调用units2tex(...) 并复制变量(单位版本和LaTeX 版本)。这是我目前的做法。输入很多,容易忘记转换或生成后来不使用的转换。
  • 使用非常短的函数名:\Sexpr{t(V)}。很难记住每个翻译函数的含义。命名空间的污染。我还记得上次我使用c 函数(在a 和b 之后)并破坏了原来的c 函数。
  • 使用某种预处理器并进行更改。正如我之前所说,所有生态系统都与考试包一起使用。这个包在后台执行 Sweave,我不想改变文件的管道来生成测试。我会写一个*.Rnw2 文件并且必须在¿sed 中创建一个脚本? ¿R?,读取文件,修改值并生成*.Rnw 文件,然后调用exams2pdf 函数...如果我忘记更新Rnw 考试文件会出现问题。我会使用 Makefile 进行协调,但我必须在终端和 Rstudio 之间切换......这个选项可能是最好的(在创建 \Sexpr 版本之后),但解决方案掩盖了管道和困难的快速问题生成检查它们。

所以,最好的方法是:是否可以创建 \Sexpr 的变体?

完整示例: 文件:“question.Rnw”

\usepackage[utf8]{inputenc}
\usepackage[OT1]{fontenc}

<<echo=FALSE, results=hide>>=
library(units)

units2tex <- function(x) {
# this function is not important here. Simplified version the original version much complex
paste0(x,deparse_unit(x))
}

@


\begin{question}

<<echo=FALSE, results=hide>>=

In <- set_units(1e-3,A)
Pn <- set_units(sample(c(2,1,0.5,0.25,0.125),1),W)

In_tex <- units2tex(In)
Pn_tex <- units2tex(Pn)

@

A resistor nah nah nah current $I_n=\Sexpr{In_tex}$ nah, nah, nah $P_n=\Sexpr{Pn_tex}$

What is V?

<<echo=FALSE, results=hide>>=
Vn <- set_units(Pn/In,V)
Vn_tex <- units2tex(Vn) 
@

\begin{answerlist}
  \item $V = \Sexpr{Vn_tex}$
  \item $V = \Sexpr{Pn_tex}$
  \item $V = \Sexpr{In_tex}$
\end{answerlist}    
\end{question}

\begin{solution}

To calculate $V$, we do $V= P_n/I_n = \frac{\Sexpr{Pn_tex}}{\Sexpr{In_tex}} = \Sexpr{Vn_tex}$
\begin{answerlist}
  \item Ok
  \item Bad
  \item Wrong
\end{answerlist}    
\end{solution}

\exname{question1}
\extype{schoice}
\exsolution{100}
\exshuffle{TRUE}

然后编译:

library(exams)
exams2html(c("question1.Rnw"), encoding="utf-8",template='plain8.html',mathjax = TRUE)

【问题讨论】:

  • 如果您包含一个简单的reproducible example 以及可用于测试和验证可能的解决方案的示例输入,则更容易为您提供帮助。
  • 嗨@jamarier,您是否觉得以下答案之一足以解决您的问题?如果是这样,请单击旁边的复选标记(在投票计数下方)接受它。然后在 StackOverflow 上相应地标记问题。

标签: r sweave r-exams


【解决方案1】:

在 Rnw 练习中,\Sexpr{} 的内容通过显式调用 as.character() 转换为字符。由于这是一个通用函数,您可以轻松定义自己的方法,例如,

as.character.units <- function(x, ...) units2tex(x, ...)

然后简单地使用\Sexpr{V} 将自动在后台调用您的units2tex() 函数。

请注意,同样不适用于 Rmd 练习。所以我想混合使用 Rnw 和 Rmd 练习,然后使用如下所示的快捷函数名称可能会更好:

u2t <- function(x, ...) units2tex(x, ...)

这需要分别称为\Sexpr{u2t(V)} 和`r u2t(V)`。

【讨论】:

  • 这解决了第一个问题(种类):使用 \Sexpr 时类型的个性化。但是第二个没有答案:Sexpr 变体的定义以表达要显示的数据中的变体。
  • 谢谢。据我所知,您的理想解决方案是不可能的(自定义\Sexpr)。所以只能结合上面的思路:不同的(子)类有不同的as.character()方法——或者——不同的短函数。
【解决方案2】:

减少污染命名空间:

a <- list(t=function(x){units2tex(x)},d=function(x){units2tex(x,digits=2)})

以后\Sexpr{a$t(V)}

它几乎比\Sexpr{V_tex} 短,但我不必定义V_tex。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-07
    相关资源
    最近更新 更多