Knitr:Markdown文档中LaTeX环境中的R代码

时间:2022-02-04 06:19:11

I have a document in Markdown, which incorporates R code via Knitr. For rendering equations I use LaTeX, simply writing its commands in the text. Say I have the following LaTeX code:

我在Markdown中有一个文档,它通过Knitr合并了R代码。对于渲染方程式,我使用LaTeX,只需在文本中编写命令即可。说我有以下LaTeX代码:

\begin{displaymath}
\mathbf{X} = \begin{bmatrix}
2 & 12\\ 
3 & 17\\ 
5 & 10\\ 
7 & 18\\ 
9 & 13\\
\end{bmatrix}
\end{displaymath}

Which renders me a nice mathematical matrix representation (in square brackets), when I convert everything to PDF (the full workflow is then: RMD -> knitr -> MD -> pandoc -> TeX -> pandoc -> PDF).

当我将所有内容转换为PDF(然后完整的工作流程:RMD - > knitr - > MD - > pandoc - > TeX - > pandoc - > PDF)时,这给我一个很好的数学矩阵表示(方括号)。

Now, suppose we want the said matrix to be generated on-the-fly from an R object, some R matrix x. In this post we establish how to generate the required LaTeX code (the matrix2latex() function is defined there). The question now is how to get Knitr to evaluate it. I tried the following code:

现在,假设我们希望从R对象即一些R矩阵x即时生成所述矩阵。在这篇文章中,我们建立了如何生成所需的LaTeX代码(在那里定义了matrix2latex()函数)。现在的问题是如何让Knitr对其进行评估。我尝试了以下代码:

\begin{displaymath}
\mathbf{X} = `r matrix2latex(x)`
\end{displaymath} 

but it simply produces blank space (NULL actually) where the R output should be. I am surprised this hasn't been asked already (at least my own search yielded nothing). Any ideas how to make this work?

但它只是产生R输出所在的空白区域(实际为NULL)。我很惊讶这已经没有被问过了(至少我自己的搜索没有产生任何结果)。任何想法如何使这项工作?

EDIT:

编辑:

As suggested, rewrote the function without cat(). Here is the working version of the function for future reference:

正如所建议的,重写了没有cat()的函数。以下是该函数的工作版本以供将来参考:

m2l <- function(matr) {

    printmrow <- function(x) {

        ret <- paste(paste(x,collapse = " & "),"\\\\")
        sprintf(ret)
    }

    out <- apply(matr,1,printmrow)
    out2 <- paste("\\begin{bmatrix}",paste(out,collapse=' '),"\\end{bmatrix}")
    return(out2)
}

1 个解决方案

#1


9  

This is because your matrix2latex function uses cat and sends its output to the standard output stream, which isn't where knitr is trying to put the output.

这是因为你的matrix2latex函数使用cat并将其输出发送到标准输出流,这不是knitr试图输出的地方。

Two solutions: one is to rewrite your function to construct the output as a string using paste and sprintf or other string formatting functions, or as a quick hack just wrap it in capture.output thus:

两个解决方案:一个是重写你的函数,使用paste和sprintf或其他字符串格式化函数将输出构造为一个字符串,或者作为快速破解将它包装在capture.output中,这样:

m2l = function(matr){capture.output(matrix2latex(matr))}

Then in your .Rmd file:

然后在.Rmd文件中:

\begin{displaymath}
\mathbf{X} = `r m2l(x)`
\end{displaymath}

becomes

\mathbf{X} = \begin{bmatrix} , 0.06099 & 0.768 \\ , 0.6112 & 0.004696 \\ , 0.02729 & 0.6198 \\ , 0.8498 & 0.3308 \\ , 0.6869 & 0.103 \\ , \end{bmatrix}

which although isn't quite perfect does illustrate the principle. The code inserted by the inline expression is the value of it, not what it prints or cats.

虽然不是很完美,但确实说明了原理。内联表达式插入的代码是它的值,而不是它打印的内容或猫。

#1


9  

This is because your matrix2latex function uses cat and sends its output to the standard output stream, which isn't where knitr is trying to put the output.

这是因为你的matrix2latex函数使用cat并将其输出发送到标准输出流,这不是knitr试图输出的地方。

Two solutions: one is to rewrite your function to construct the output as a string using paste and sprintf or other string formatting functions, or as a quick hack just wrap it in capture.output thus:

两个解决方案:一个是重写你的函数,使用paste和sprintf或其他字符串格式化函数将输出构造为一个字符串,或者作为快速破解将它包装在capture.output中,这样:

m2l = function(matr){capture.output(matrix2latex(matr))}

Then in your .Rmd file:

然后在.Rmd文件中:

\begin{displaymath}
\mathbf{X} = `r m2l(x)`
\end{displaymath}

becomes

\mathbf{X} = \begin{bmatrix} , 0.06099 & 0.768 \\ , 0.6112 & 0.004696 \\ , 0.02729 & 0.6198 \\ , 0.8498 & 0.3308 \\ , 0.6869 & 0.103 \\ , \end{bmatrix}

which although isn't quite perfect does illustrate the principle. The code inserted by the inline expression is the value of it, not what it prints or cats.

虽然不是很完美,但确实说明了原理。内联表达式插入的代码是它的值,而不是它打印的内容或猫。