【问题标题】:Replacing the "print" function in knitr chunk evaluation替换 knitr 块评估中的“打印”功能
【发布时间】:2013-03-14 01:22:23
【问题描述】:

我想在编译 knitr rmarkdown 文档时将“pander”功能设置为替代“打印”功能。像这样(在 R 中运行的代码示例):

require(pander)
print <- function(...) pander(..., style = "rmarkdown") # makes sure that everyhing that everyprint will pass through pander
summary(cars)

这将导致:

> summary(cars)

----------------------------------
&nbsp;    speed          dist     
------ ------------ --------------
 ****  Min.  : 4.0   Min.  : 2.00 

 ****  1st Qu.:12.0 1st Qu.: 26.00

 ****  Median :15.0 Median : 36.00

 ****   Mean :15.4   Mean : 42.98 

 ****  3rd Qu.:19.0 3rd Qu.: 56.00

 ****  Max.  :25.0  Max.  :120.00 
----------------------------------

这样,我将获得所有表格的良好格式,而不是手动需要在整个文档中编写“pander”(想象我必须在文档中编写“summary(car) 20 次,更改“print”将节省我写 pander(summary(car)) )。

这可能吗? (或者有没有我不知道的更聪明的方法?)

谢谢。

更新:.rmd 文件的示例:

TEST
====

```{r}

require(pander)
print <- function(...) pander(..., style = "rmarkdown") # makes sure that everyhing that everyprint will pass through pander

summary(cars)
```


```{r, eval=FALSE}
library(knitr)
knit2html("test.rmd") # http://stackoverflow.com/questions/10646665/how-to-convert-r-markdown-to-html-i-e-what-does-knit-html-do-in-rstudio-0-9
# http://quantifyingmemory.blogspot.co.il/2013/02/reproducible-research-with-r-knitr.html
```

而输出 test.md 是:

TEST
====




```r

require(pander)
print <- function(...) pander(..., style = "rmarkdown")  # makes sure that everyhing that everyprint will pass through pander

summary(cars)
```

```
##      speed           dist    
##  Min.   : 4.0   Min.   :  2  
##  1st Qu.:12.0   1st Qu.: 26  
##  Median :15.0   Median : 36  
##  Mean   :15.4   Mean   : 43  
##  3rd Qu.:19.0   3rd Qu.: 56  
##  Max.   :25.0   Max.   :120
```






```r
library(knitr)
knit2html("test.rmd")  # http://stackoverflow.com/questions/10646665/how-to-convert-r-markdown-to-html-i-e-what-does-knit-html-do-in-rstudio-0-9
#
# http://quantifyingmemory.blogspot.co.il/2013/02/reproducible-research-with-r-knitr.html
```

【问题讨论】:

  • 是的,但是没有用。生成的 .md 文件不接受更改。
  • 我认为您需要扩展您的问题,特别是因为“需要在整个文档中编写 'pander'”有点含糊。
  • 通用print 函数正在为您尝试打印的对象调用什么方法?如果我在新的 R 会话中键入 methods( print ),则有 171 种打印方法可用。
  • Spacedman 和 Simon,我添加了一个示例。我希望这可以澄清。是的,我知道 print 有很多方法,但是对于有很多表格的文档,用“pander”替换它会对我“起作用”。 (同样,如果有人可以提供一个更聪明的选择会更好)
  • p.s:我不理解否决票,我认为这是一个合法且有用的问题。

标签: r knitr r-markdown


【解决方案1】:

我试图尽量减少基于@malcook 的function 的误报和否定。

误报可能非常“昂贵”:在 knitr/rmarkdown 中调用时,在 ggplot2 对象和 data.frame 分配上调用 pander 会导致无休止的挂起而没有错误消息。我输入了package

```{r}
pander_handler = function(x, ..., row.names = FALSE, dont_transform = c("knit_asis")) {
    anyS3method = function(x) {
        classes = class(x)
        any(
            sapply(classes, FUN = function(classes) {
                !is.null(utils::getS3method('pander',classes, TRUE, environment(pander::pander)))
            })
        )
    }
    if (length(intersect(dont_transform, class(x))) == 0 && anyS3method(x)) {
        pander::pander(x, row.names = row.names, ...) # if pander has a method, we use it
    } else {
        res = withVisible(knitr::knit_print(x, ...))
        # indicate the htmlwidget result with a special class so we can attach
        # the figure caption to it later in wrap.knit_asis
        if (inherits(x, 'htmlwidget'))
            class(res$value) = c(class(res$value), 'knit_asis_htmlwidget')
        if (res$visible) res$value else invisible(res$value)
    }

}

opts_chunk$set(render = pander_handler)
```

```{r}
library(data.table)
library(pander)
library(knitr)
library(ggplot2)
qplot(1:2)
plot(1:2)
xtabs(~ mpg + cyl, data = mtcars)
table(mtcars$cyl)
"blabla"
```

```{r}
xy = data.frame(x = 1:2, y = 3:4)
xy
```


```{r}
xx = data.table(xy)
xx[, new := 3:4]
```

```{r}
pander(xtabs(~ y, data = xx), caption = "y")
```


```{r}
library(lme4)
summary(lmer(Reaction ~ Days + (Days | Subject), sleepstudy))
summary(lm(Reaction ~ Days, sleepstudy))
```

【讨论】:

    【解决方案2】:

    我认为目前最好的选择是添加opts_chunk$set(results="asis", render=pander)。然后,这将使用 pander 渲染所有块。

    例如

    ```{r set_knitr_chunk_options, echo=FALSE, message=FALSE}
    require(knitr)
    require(pander)
    opts_chunk$set(results = "asis", render=pander) # important for making sure the output will be well formatted.
    ```
    
    ```{r}
    USJudgeRatings
    ```
    

    【讨论】:

      【解决方案3】:

      另一种(当前的解决方法)方法是覆盖 evaluate:::default_output_handler 以对具有 pander 方法的结果进行 panderize,如下所述:

      https://github.com/yihui/knitr/issues/484#issuecomment-32705187

      令人高兴的是,这种方法不需要“需要在整个文档中写入“pander””或“有选择地否决要使用 pander 打印的对象类的打印方法”。

      【讨论】:

        【解决方案4】:

        对于未来的读者 -

        根据 Ramnath 的回答,可以简单地使用:

        require(pander)
        print <- function (x, ...) UseMethod("pander")
        

        更新:我在以下博客文章中组装了一个清晰的演练示例,以激发上述问题 - Write MS-Word document using R (with as little overhead as possible)

        【讨论】:

          【解决方案5】:

          您需要有选择地否决要使用 pander 打印的对象类的打印方法。做methods(pander) 找出可用的东西。有些方法没有导出,所以你必须使用::: 来访问它们。这是一个简单的例子。

          TEST
          ====
          
          ```{r cache = F, comment = NA}
          print.lm <- pander:::pander.lm
          lm(mpg ~ wt, data = mtcars)
          ```
          

          输出

          TEST
          ====
          
          
          ```r
          print.lm <- pander:::pander.lm
          lm(mpg ~ wt, data = mtcars)
          ```
          
          ```
          
          --------------------------------------------------------------
                     &nbsp;  Estimate   Std. Error   t value   Pr(>|t|) 
          ----------------- ---------- ------------ --------- ----------
            **(Intercept)**   37.29       1.878       19.86   8.242e-19 
          
                     **wt**   -5.344      0.5591     -9.559   1.294e-10 
          --------------------------------------------------------------
          
          Table: Fitting linear model: mpg ~ wt
          ```
          

          【讨论】:

          • 我觉得你也需要results='asis'
          • 嗨一辉,我使用:opts_chunk$set(results = "asis")
          • 你能不能把它作为一个钩子来实现,这样如果你这样做{r pander=TRUE},它会破坏打印功能,否则它会像往常一样?
          猜你喜欢
          • 2018-01-03
          • 1970-01-01
          • 2015-02-27
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-11-29
          相关资源
          最近更新 更多