在 RMarkdown 中的 HTML 模板中渲染 ggplot2 绘图

Posted

技术标签:

【中文标题】在 RMarkdown 中的 HTML 模板中渲染 ggplot2 绘图【英文标题】:Render ggplot2 plot in HTML template within RMarkdown 【发布时间】:2021-12-19 02:38:57 【问题描述】:

我已经在 rmarkdown 中构建了一个函数来生成一些具有给定值的 html 输出,但是如果传递的值之一引用了 ggplot 对象,我希望它能够工作。

基本上,knitr 完美地呈现了这一点:

x <- [R computation]
y <- [ggplot figure]

<div id="some_number">`r x`</div>
<div id="some_figure">
```r
y
```
</div>

但我不想每次使用具有不同xy 的特定html 块时都必须重写它。于是我写了如下函数:

html_func <- function(x,y) 

    template <- "
<div id=\"some_num\">x</div>
<div id=\"some_fig\">y</div>
    "

    instance <- glue::glue(template)
    output <- knitr::asis_output(instance)

    return(output)


number <- [R computation]
figure <- [ggplot figure]

html_func(number, figure)

渲染的页面显示在 div 中正确计算的“数字”,但不渲染绘图。

如何让它在 HTML 容器中生成绘图?

更新:评论者建议使用实时数据,所以我们开始吧。

这行得通:

```r
library(ggplot2)
data(mtcars)

number <- mean(mtcars$mpg)
figure <- ggplot2::ggplot(mtcars, aes(x=hp, y=mpg)) + 
    geom_point()
```
<div id="some_number">`r number`</div>
<div id="some_figure">
```r echo=FALSE
figure
```
</div>

但事实并非如此。计算输出正常,但绘图不渲染。

```r
library(ggplot2)
data(mtcars)

number <- mean(mtcars$mpg)
figure <- ggplot2::ggplot(mtcars, aes(x=hp, y=mpg)) + 
    geom_point()

html_func <- function(x,y) 

    template <- "
<div id=\"some_num\">x</div>
<div id=\"some_fig\">y</div>
        "

    instance <- glue::glue(template)
    output <- knitr::asis_output(instance)

    return(output)


html_func(number, figure)
```

这是比较两者的屏幕截图。

【问题讨论】:

希望在示例中很清楚 [] 中的文本只是任意内容的占位符,而不是实际语法。 我无法让你的函数工作(也许显示一些允许它为你工作的实际对象?)但我想知道你是否需要一个明确的print() 用于情节。无论如何,这在 results = "asis" 样式块中是必要的。 谢谢@aosmith。我更新了帖子以纠正一个可能导致问题的小错误,用数据复制了问题,并显示了我的输出。 您可以使用print(figure) 而不仅仅是figure 来获取绘图,但看起来您仍然可以获得打印的对象。您是附加到knitr::asis_output() 还是考虑使用results = "asis" 块?不过,我从来没有用过用 R 输出编写 HTML,只有 markdown,所以也许这是个问题。 如您所述,print(figure) 生成了绘图,但未在 HTML 容器中呈现,并且打印的对象仍然出现。我没有与knitr::asis_output() 结婚,但做r results="asis"] 会产生同样的结果。 【参考方案1】:

所以这是一个糟糕的解决方案。

```r
html_func_open <- function(x) 

    template <- "
<div id=\"some_num\">x</div>
<div id=\"some_fig\">
    "

    instance <- glue::glue(template)
    output <- knitr::asis_output(instance)

    return(output)


html_func_close <- function() 
      template <- "
</div>
    "

    instance <- glue::glue(template)
    output <- knitr::asis_output(instance)

    return(output)


html_func_open(number)
figure
html_func_close()
```

通过在 HTML 模板之外进行绘图,然后在第二个函数中关闭 HTML,我得到了我想要的输出。这使得图形两侧的 HTML 可以像我想要的那样复杂。但这并不是一个真正理想的解决方案,因为每次我想添加一个新图形时都需要多行,这限制了我构建 HTML 容器的复杂性。

所以仍然在寻找更好的解决方案,我可以将图形传递给函数并让它正确渲染。

【讨论】:

以上是关于在 RMarkdown 中的 HTML 模板中渲染 ggplot2 绘图的主要内容,如果未能解决你的问题,请参考以下文章

Rmarkdown HTML 渲染问题

rmarkdown 中的内部链接不起作用

带有外部和嵌入式 yaml 的 RMarkdown

RMarkdown:使用 Rcpp 中的 rmarkdown:render-function 生成 pdf 文档

shinyApp 没有将 Rmarkdown 文件呈现为 RStudio

渲染模板 django cms 插件中的简单循环