【问题标题】:Use hooks to format table in output使用钩子在输出中格式化表格
【发布时间】:2013-11-09 14:49:10
【问题描述】:

使用 knitr 和 R Markdown,我可以使用以下命令从矩阵生成表格输出:

```{r results='asis'}
kable(head(x))
```

但是,我正在寻找一种方法来使 kable 代码隐式化,因为我不想用它来混淆回显的代码。本质上,我想要这个:

```{r table=TRUE}
head(x)
```

... 生成格式化的表格(而不是普通的output='markdown')输出。

我实际上认为这必须非常简单,因为这是一个非常明显的要求,但我找不到任何方法来实现这一点,无论是通过文档还是在网络上。

我创建输出挂钩的方法失败了,因为一旦数据到达挂钩,它已经格式化,不再是原始数据。即使指定results='asis',钩子也会以字符串而不是矩阵的形式获取输出。这是我尝试过的:

default_output_hook <- knit_hooks$get('output')
knit_hooks$set(output = function (x, options)
    if (! is.null(options$table))
        kable(x)
    else
        default_output_hook(x, options)
)

但就像我说的,这会失败,因为 x 不是原始矩阵,而是一个字符串,我为 results 选项指定的值并不重要。

【问题讨论】:

标签: r markdown knitr


【解决方案1】:

现在可以在 YAML 标头中设置df_print

---
output:
  html_document:
    df_print: kable  
---

```{r}
head(iris)
```

【讨论】:

    【解决方案2】:

    我认为其他答案来自以下不起作用的时间,但现在我们可以这样做:

    ```{r results='asis', render=pander::pander}
    head(x)
    ```
    

    或者为设置块中的所有块设置这个,例如:

    ```{r setup, include=FALSE}
    knitr::opts_chunk$set(echo = TRUE, render=pander::pander)
    ```
    

    【讨论】:

      【解决方案3】:

      由于缺乏更好的解决方案,我目前正在重新解析我在钩子中收到的字符串表示。我把它贴在这里,因为它有点工作。但是,解析数据框的字符串表示形式从来都不是完美的。除了我自己的数据之外,我没有尝试过以下任何方法,我完全希望它能够在一些常见的用例中打破。

      reparse <- function (data, comment, ...) {
          # Remove leading comments
          data <- gsub(sprintf('(^|\n)%s ', comment), '\\1', data)
          # Read into data frame
          read.table(text = data, header = TRUE, ...)
      }
      
      default_output_hook <- knit_hooks$get('output')
      
      knit_hooks$set(output = function (x, options)
          if (is.null(options$table))
              default_output_hook(x, options)
          else {
              extra_opts <- if (is.list(options$table)) options$table else list()
              paste(kable(do.call(reparse, c(x, options$comment, extra_opts))),
                    collapse = '\n')
          }
      )
      

      如果 R 降价 comment 选项设置为包含正则表达式特殊字符(例如 *)的字符序列,则此 中断,因为 R 似乎没有明显的转义正则表达式的方法。

      这是一个用法示例:

      ```{r table=TRUE}
      data.frame(A=1:3, B=4:6)
      ```
      

      您可以将额外的参数传递给deparse 函数。这是必要的,例如当表包含NA 值时,因为read.table 默认将它们解释为字符串:

      ```{r table=list(colClasses=c('numeric', 'numeric'))}
      data.frame(A=c(1, 2, NA, 3), B=c(4:6, NA))
      ```
      

      远非完美,但至少它有效(在很多情况下)。

      【讨论】:

      • 这对于宽矩阵失败,因为它们的行被分成多行。叹息。
      • 这太骇人听闻了。希望在 12 月会有一种更自然的方式来做到这一点。我现在正忙于其他事情。
      • @Yihui 好消息,谢谢。 “这太骇人听闻了”——当你阅读“重新解析”时就应该清楚这一点。 ;-)
      • 是的。我的目标是在重新解析中删除前缀“re”:)
      • 这已经晚了,但可能会有所帮助。我通过将evaluate() 应用于knit_hooks$set() 源,然后将Kable 代码here 解决了这个问题。
      【解决方案4】:

      不完全是您要查找的内容,但我在这里发布了一个答案(无法放入评论),因为您描述的工作流程与我开始工作时的初始目标和用例非常相似我的pander 包。虽然我真的很喜欢 knitr 中提供的大量块选项,但我希望有一个引擎可以让创建文档变得非常容易、自动且无需任何必要的调整。我知道knitr 钩子真的很强大,但我只是想在我的Rprofile 中设置一些东西,让识字编程工具顺利工作,这对我来说最终是Pandoc.brew .

      主要思想是指定一些选项(你使用什么降价风格,你的小数点是什么,图表最喜欢的颜色等),然后简单地用 brew 语法编写你的报告,没有任何块选项,您的代码结果将自动转换为降价。然后使用 Pandoc 将其转换为 pdf/docx/odt 等。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-12-19
        • 2017-06-28
        • 1970-01-01
        • 2020-03-16
        • 1970-01-01
        • 2011-08-21
        • 2019-02-05
        相关资源
        最近更新 更多