For R Markdown, How do I display a matrix from R variable

前端 未结 4 1104
没有蜡笔的小新
没有蜡笔的小新 2021-02-05 23:14

I have a rmd document where I have the following

```{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          


        
4条回答
  •  情话喂你
    2021-02-05 23:31

    This is a perfect use case for knitr::knit_print().
    You will find details about the knitr::knit_print() method in its dedicated vignette:

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

    The goal is to provide a knit_print method for objects of class matrix. As other answers suggested, it could be useful to define operators.

    You will find below an Rmd file that provides a solution to your problem. It also contains a proposal for operators.

    The main feature of this answer is that you only have to write

    `r A`
    

    to output the matrix A in LaTeX inline mode (no $ to type) and write

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

    to write in LaTeX display mode.

    I also propose you to define a %times% operator. Therefore, you only have to write:

    `r A %times% B`
    

    This answer is quite generic and you should be able to extend it to other objects.

    ---
    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
    ```
    

提交回复
热议问题