对于R Markdown,如何显示R变量的矩阵

时间:2017-08-09 12:54:21

标签: r matrix latex r-markdown

我有一份rmd文件,其中包含以下内容

```{r code_block, echo=FALSE}
A = matrix(c(1,3,0,1),2,2)
B = matrix(c(5,3,1,4),2,2)
```

$$
\begin{bmatrix} 
1  & 0 \\ 
3 & 1 \\ 
\end{bmatrix}
*
\begin{bmatrix} 
5 & 1 \\ 
3 & 4 \\ 
\end{bmatrix}
$$

现在我想手动硬编码LaTeX部件,而不是使用变量A和B中的矩阵。怎么可以这样做?

感谢。

4 个答案:

答案 0 :(得分:4)

直接,您可以编写乳胶线。 writeLines()cat()会有所帮助。

您可以将apply(A, 1)与两步paste()一起使用。

  1. paste(collpase = "&"):折叠每一行
  2. paste(, "\\\\"):使用\\
  3. 折叠每列

然后我们可以获得矩阵的latex公式。

write_matex <- function(x) {
  begin <- "$$\\begin{bmatrix}"
  end <- "\\end{bmatrix}$$"
  X <-
    apply(x, 1, function(x) {
      paste(
        paste(x, collapse = "&"),
        "\\\\"
      )
    })
  writeLines(c(begin, X, end))
}

如果执行此功能,write_matex(A)会给出

$$\begin{bmatrix}
1&0 \\
3&1 \\
\end{bmatrix}$$

使用块选项{r, results = 'asis'}时,您可能会在pdf和html中看到矩阵。

enter image description here


乳胶块

基于此功能,您可以在乳胶块中自由使用矩阵。为此,应在函数中删除$$。代替writeLines(),可以使用paste(collapse = "")

write_matex2 <- function(x) {
  begin <- "\\begin{bmatrix}"
  end <- "\\end{bmatrix}"
  X <-
    apply(x, 1, function(x) {
      paste(
        paste(x, collapse = "&"),
        "\\\\"
      )
    })
  paste(c(begin, X, end), collapse = "")
}

在文本部分,您可以将该功能实现为

$$
`r write_matex2(A)` \times `r write_matex2(B)`
$$

r markdown中,带反引号的r可以附加您的r函数和变量。这样你就可以得到

enter image description here

如您所见,这是可重复的。

(C <- matrix(1:10, nrow = 2))
#>      [,1] [,2] [,3] [,4] [,5]
#> [1,]    1    3    5    7    9
#> [2,]    2    4    6    8   10

类似地,

$$`r write_matex2(C)` + `r write_matex2(C)`$$

enter image description here

答案 1 :(得分:3)

这是knitr::knit_print()的完美用例。
您可以在专用的插图中找到有关knitr::knit_print()方法的详细信息:

vignette('knit_print', package = 'knitr')

目标是为类knit_print的对象提供matrix方法。正如其他答案所建议的那样,定义运算符可能会有用。

您将在Rmd文件下面找到可以解决您问题的文件。它还包含针对运营商的建议。

此答案的主要特点是您只需要编写

`r A`

以LaTeX内联模式输出矩阵A(无需键入$)并写入

```{r echo=FALSE}
A
```

以LaTeX显示模式编写。

我还建议您定义一个%times%运算符。因此,您只需要编写:

`r A %times% B`

这个答案很通用,您应该可以将其扩展到其他对象。

---
title: "R Markdown: Display a Matrix for R Variable"
author: "Romain Lesur"
output: 
  html_document:
    keep_md: true
---

```{r setup, include=FALSE}
# Define a generic method that transforms an object x in a LaTeX string
as_latex = function(x, ...) {
  UseMethod('as_latex', x)
}

# Define a class latex for LaTeX expressions
as_latex.character = function(x) {
  structure(
    paste(x, collapse = ' '), 
    class = c('latex', 'character')
  )
}

# A character string of class latex is rendered in display mode
# Define a knit_print() method for the latex class
knit_print.latex = function(x, ...) {
  knitr::asis_output(
    paste0('$$', x, '$$')
  )
} 

# Now, define a method as_latex for matrix
as_latex.matrix = function(x, ...) {
  as_latex(c(
    '\\begin{bmatrix}',
    paste(
      t(x),
      rep(c(rep('&', nrow(x) - 1), '\\\\'), ncol(x)),
      collapse = ''
    ),
    '\\end{bmatrix}'
  ))
}

# Indicate to knitr that matrix are rendered as latex
knit_print.matrix = function(x, ...) {
  knitr::knit_print(as_latex(x))
}

# Build a knitr inline hook to display inline latex in inline mode
default_inline_hook = knitr::knit_hooks$get('inline')
knitr::knit_hooks$set(inline = function(x) {
  x = paste(gsub('\\$\\$', '$', x))
  default_inline_hook(x)
})
```


```{r}
A = matrix(c(1,3,0,1),2,2)
B = matrix(c(5,3,1,4),2,2)
```


Now, matrix are rendered as LaTeX:

Matrix A in inline mode: `r A`

Matrix A in display mode:

```{r echo=FALSE}
A
```


### Operators

As other answers suggested, it could be useful to define operators.  
With the previous class, it is relatively straightforward:

```{r operators, include=FALSE}
`%times%` = function(x, y) {
  as_latex(sapply(list(x, '\\times', y), as_latex))  
}

`%add%` = function(x, y) {
  as_latex(sapply(list(x, '+', y), as_latex))  
}
```

Example in inline mode: `r A %add% A %times% B`

Display mode:
```{r echo=FALSE}
A %times% B
```

答案 2 :(得分:2)

我想出了一个将矩阵中的数字插入正确的LaTeX代码的函数。在使用它的代码块中,您需要results='asis'才能渲染LaTeX,并且可以将函数与所需的其他部分一起包装在writeLines中。

我仍然愿意接受更优雅的解决方案。

```{r}
A <- matrix(c(1, 3, 0, 1), 2, 2)
B <- matrix(c(5, 3, 1, 4), 2, 2)

# Utility function to print matrices in proper LaTeX format
print_mat <- function(mat) {
  n <- nrow(mat)
  c('\\begin{bmatrix}',
    paste0(sapply(seq_len(n - 1),
                  function(i) paste0(mat[i, ], collapse = ' & ')),
           ' \\\\'),
    paste0(mat[n, ], collapse = ' & '),
    '\\end{bmatrix}')
} 

```

```{r, results = 'asis'}
writeLines(c('$$',
             print_mat(A),
             '\\times',
             print_mat(B),
             '$$'))
```

Picture of resulting output

答案 3 :(得分:0)

您好,您可以在降价区块中使用library(printr)

knitr::kable(A ,  caption = "matrix A")

https://yihui.name/printr/

像这样

```{r code_block, echo=FALSE}
A = matrix(c(1,3,0,1),2,2)
B = matrix(c(5,3,1,4),2,2)
knitr::kable(A ,  caption = "matrix A")
```