【问题标题】:How can I embed a plot within a RMarkdown table?如何在 RMarkdown 表中嵌入绘图?
【发布时间】:2017-01-14 16:32:21
【问题描述】:

我正在尝试在 RMarkdown 中生成报告模板。在这份报告中,我想在我正在使用的调查中问题的编号和文本旁边的单元格中绘制一个图。我生成了一些示例图,并在 MS Word 中制作了以下示例。是否可以将 R 生成的图放在 RMarkdown 的表格中?

如果是这样,代码会是什么样子?

编辑 (9/8/16): 我现在包含 .Rmd 文件。问题是 html 文件无法编译并显示以下消息。

pandoc: Could not fetch Template1_files/figure-html/score_table-1.png
Template1_files/figure-html/score_table-1.png: openBinaryFile: does not exist (No such file or directory)
Error: pandoc document conversion failed with error 67
Execution halted

Template1 为文件名,score_table 为块标签。

有人愿意帮我诊断问题吗?

<meta charset="utf-8">
---
title: "Untitled"
author: "Xander"
date: "September 7, 2016"
output: html_document
    self_contained: false
---

```{r mychunk, fig.show = "hide", echo = FALSE, fig.height=3, fig.width=5}
library(knitr)
library(ggplot2)

# sample data
dat <- data.frame(text = sapply(1:10, FUN = function(x) { paste0(sample(x = LETTERS, size = 15), collapse = "") }))
score_set = replicate(n = 10, expr = {data.frame(other = c("other", "other", "other", "other"), score=sample(1:7,4,TRUE))},simplify = F)

#Plot Function
plotgen<-function(score_set,other,score){
  p <- ggplot(score_set, aes(factor(other), score))
  p + geom_violin(fill = "#99CCFF") + coord_flip() + scale_x_discrete(name=NULL) +
  scale_y_continuous(breaks = round(seq(1, 7, by = 1),1), limits = c(1,7), name=NULL) + theme(axis.text.y=element_blank(),axis.title.y=element_blank(),axis.ticks.y=element_blank(),
      panel.grid.major.y = element_line(colour = "black"),
      panel.grid.minor = element_blank(),
      panel.background = element_rect(fill = "white"),
      panel.border = element_rect(colour = "black", fill=NA, size=1)) +
geom_hline(yintercept=sample(1:7,1,TRUE), size = 1.5, colour = "#334466")
}

# generate plots
invisible(lapply(seq_along(score_set), FUN = function(x) {plotgen(score_set[[x]],other,score)}))

out <- cbind(row.names(dat), 
         as.character(dat$text), 
         sprintf("![](%s%s-%s.png)", opts_current$get("fig.path"), opts_current$get("label"), 1:nrow(dat)))
kable(out, col.names = c("ID", "Text", ""))
````

【问题讨论】:

    标签: r plot knitr r-markdown


    【解决方案1】:

    ggplot2

    这现在是可能的:

    library(ggplot2)
    
    # Create a ggplot plot
    plot_object <-
      ggplot(
        data = gtcars,
        aes(x = hp, y = trq,
            size = msrp)) +
      geom_point(color = "blue") +
      theme(legend.position = "none")
    
    # Create a tibble that contains two
    # cells (where one is a placeholder for
    # an image), then, create a gt table;
    # use the `text_transform()` function
    # to insert the plot using by calling
    # `ggplot_object()` within the user-
    # defined function
    tab_1 <-
      dplyr::tibble(
        text = "Here is a ggplot:",
        ggplot = NA
      ) %>%
      gt() %>%
      text_transform(
        locations = cells_body(columns = ggplot),
        fn = function(x) {
          plot_object %>%
            ggplot_image(height = px(200))
        }
      )
    

    来源[21/01/2022]:https://gt.rstudio.com/reference/ggplot_image.html

    【讨论】:

      【解决方案2】:

      您可以执行以下操作(对于基础图,对于ggplot2 图 - 请参阅最底部的评论):

      ```{r mychunk, fig.show = "hide", echo = FALSE, fig.height=3, fig.width=5}
      library(knitr)
      # sample data
      dat <- data.frame(
        text = sapply(1:10, FUN = function(x) { paste0(sample(x = LETTERS, size = 15), collapse = "") }), 
        x1 = rnorm(10), 
        x2 = rnorm(10, mean = 3), 
        x3 = rnorm(10, mean = 5))
      
      # generate plots
      invisible(apply(dat[, 2:4], MARGIN = 1, FUN = boxplot))
      
      out <- cbind(row.names(dat), 
                   as.character(dat$text), 
                   sprintf("![](%s%s-%s.png)", opts_current$get("fig.path"), opts_current$get("label"), 1:nrow(dat)))
      kable(out, col.names = c("ID", "Text", "Boxplot"))
      ```
      
      • apply(dat[, 2:4], MARGIN = 1, FUN = boxplot) 使用来自x1x2x3 的数据生成箱线图。由于fig.show="hide",这些数字已生成但未包含在文档中。
      • sprintf("![](%s%s-%s.png)", opts_current$get("fig.path"), opts_current$get("label"), 1:nrow(dat)) 生成 markdown 语法以包含绘图。这类似于calling include_graphics,但优点是我们将降价作为字符向量。
      • 最后,kable 生成表格。

      或者,您可以手动生成表格,使用 Pandoc 的 pipe_table as shown here 提供更多灵活性。

      上面代码的输出:

      Gregor's answer here 显示如何将其应用于ggplot2 绘图:逐个元素打印apply 返回的list,即invisible(apply(...)) 变为invisible(lapply(apply(...), print))

      【讨论】:

      • 感谢您的回复。这看起来很有希望。我有一个关于如何在 RMarkdown 中生成未显示图像的路径的澄清问题。用我在 ggplot2 中生成图表的函数替换 boxplot 函数后,出现以下错误:pandoc: Could not fetch Template1_files/figure-html/mychunk-1.png ggplot2 绘图的路径与基本包绘图不同吗?使用sprintf() 时是否必须以不同方式指定它?再次感谢您的帮助。
      • 不,ggplot 应该无关紧要。但是可以设置self_contained: false,编译后查看文件路径。当然,你需要将mychunk替换为已经生成plot的chunk的label。
      • 感谢您的回复。我之前确实尝试过检查文件路径,但没有使用self_contained: false。不幸的是,file.exists(paste(getwd(),"/Template1_files/figure-html/score_table-1.png",sep = "")) 在编译后仍然返回 false。 (块的标签是'score_table'。)我仔细检查了在没有invisible()的情况下生成表格时是否出现了表格。您还有其他建议可以帮助诊断问题吗?
      • 对不起,我之前的评论是错误的:ggplot 确实很重要。问题是,ggplots 只有在 打印 时才会生成。用print 替换更新代码中的invisible 可以解决该问题。但是,这会使文档因不需要的输出而变得混乱。目前,我不知道如何避免这种情况。请考虑提出一个关于如何在循环中生成 ggplots 并生成文件而不打印任何可见输出的新问题。这似乎是一个非常特殊的问题,大部分与您的原始问题无关。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-08-02
      • 1970-01-01
      • 1970-01-01
      • 2016-07-26
      • 1970-01-01
      • 1970-01-01
      • 2017-05-02
      相关资源
      最近更新 更多