使用带有 programmatically-generated、交错、headers 和图形的 RMarkdown 生成 Word 文档

Producing a Word document using RMarkdown with programmatically-generated, interleaved, headers and graphs

背景:

在解决了上面的上一个问题后,我现在有一个 .Rmd 文件,它将生成一个包含 headers 部分、图表和 table 内容的 Word 文档。

以下问题仍然存在:

  1. headers 部分和图表没有交错。我目前拥有的是:

header1

标题 2

header3

图 1

图 2

图 3

我的代码应该如何修改以产生:

header1

图 1

标题 2

图 2

header3

图 3

代替?

  1. word文档包含方括号中的数字,例如“[[1]]”、“[[2]]”等,我相信它们会与图表一起打印出来。如何删除这些?

  2. 对于每张图,我想要一个样板句,其中包含关于数据的陈述,特别是位于虚线之外的数据点的数量,距离均值 +/- 2SD。我尝试通过包括例如

    来添加它
report.data %>% 
dplyr::filter(identifier == x) %>%
paste(eval("r sum(result < mean(result) - 2 * sd(result))"), " results out of bounds.") 

在函数中,但这会将图形转换为文本 (!)。

一如既往,我们将不胜感激任何可以提供的帮助或建议 - 感谢您的阅读!

生成示例数据和生成报告的脚本:

library(dplyr)
set.seed(1234)

test1.level1.analyser1 <- data.frame(
  result = rnorm(25, mean = 2.5, sd = 0.2), 
  test = c("test1"), 
  level = c("level1"), 
  sample.no = c(1:25), 
  analyser = c("analyser1")
  )

test1.level1.analyser2 <- data.frame(
  result = rnorm(25, mean = 2.6, sd = 0.1), 
  test = c("test1"), 
  level = c("level1"), 
  sample.no = c(1:25), 
  analyser = c("analyser2")
  )

test1 <- rbind(test1.level1.analyser1, test1.level1.analyser2)

test2.level1.analyser1 <- data.frame(
  result = rnorm(25, mean = 10, sd = 2), 
  test = c("test2"), 
  level = c("level1"), 
  sample.no = c(1:25), 
  analyser = c("analyser1")
  )

test2.level1.analyser2 <- data.frame(
  result = rnorm(25, mean = 9.5, sd = 0.75), 
  test = c("test2"), 
  level = c("level1"), 
  sample.no = c(1:25), 
  analyser = c("analyser2"))

test2.level2.analyser1 <- data.frame(
  result = rnorm(25, mean = 30, sd = 1.8), 
  test = c("test2"), 
  level = c("level2"), 
  sample.no = c(1:25), 
  analyser = c("analyser1")
  )

test2.level2.analyser2 <- data.frame(
  result = rnorm(25, mean = 25, sd = 0.75), 
  test = c("test2"), 
  level = c("level2"), 
  sample.no = c(1:25), 
  analyser = c("analyser2"))
test2.level2 <- rbind(test2.level2.analyser1, test2.level2.analyser2)

test2 <- rbind(test2.level1, test2.level2)

write.csv(test1, "test1.csv", row.names = FALSE)
write.csv(test2, "test2.csv", row.names = FALSE)

###
report.data <- rbind(test1, test2) %>% mutate(identifier = paste(test, level, sep = " ")) 
rmarkdown::render("report.Rmd", params = list(report.data = report.data), output_file = "intersite.comparison.report.doc")

report.Rmd 文件:

---
title: "Inter-site IQC Comparison Report"
output: word_document
toc: yes
---

```{r setup, include=FALSE, comment = "", results = 'asis', echo = FALSE}
library(dplyr)
library(ggplot2)
library(purrr)
knitr::opts_chunk$set(echo = FALSE)

 my_plot <- function(df) {
    ggplot(df, aes(x = sample.no, y = result)) +
    geom_point(aes(colour = analyser)) +
    geom_hline(aes(yintercept = mean(result) + 2 * sd(result)), colour = "red", linetype = "dashed") +
    geom_hline(aes(yintercept = mean(result) - 2 * sd(result)), colour = "red", linetype = "dashed") +
    theme_classic() +
    theme(legend.title = element_blank()) +
    labs(
      # the title above the plot, based on information in the filtered df
      title = paste0("Inter-site comparison for ", unique(df$identifier)),
      x = "Sample number",
      y = "Result",
      # the text below, based on data in the filtered data frame
      caption = paste0("Caption here.")) +
    expand_limits(y = 0) +
    coord_cartesian(xlim = c(0, max(df$sample.no) + 2)) +    
    theme(
      # configure the caption / sentence below
      plot.caption=element_text(size=12, hjust = 0, margin = margin(t=20)),
      # add some buffer at bottom as spacing between plots
      plot.margin = margin(b=50)
    )
}
```

```{r, comment = "", results = 'asis', echo = FALSE}
purrr::map(unique(report.data$identifier),
                           function(x) {
                             #section heading
                             cat("#", (x), "\n")
                             # filter data before passing it to the plot function
                             report.data %>% 
                               dplyr::filter(identifier == x) %>%
                               my_plot()
                             #report.data %>% 
                               #dplyr::filter(identifier == x) %>%
                               #paste(eval("r sum(result < mean(result) - 2 * sd(result))"), " results out of bounds.")
                           }
)
```

编辑:地图功能代码的当前版本,遵循 Sean van der Merwe 的善意建议,如下:

purrr::map(unique(report.data$identifier),
                           function(x) {
                             #section heading
                             cat("#", (x), "\n")
                             cat("\n\n")
                             # filter data before passing it to the plot function
                             report.data %>% 
                               dplyr::filter(identifier == x) %>%
                               my_plot() %>% print()
                             cat("\n\n")
                             #report.data %>% 
                               #dplyr::filter(identifier == x) %>%
                               #paste(eval("r sum(result < mean(result) - 2 * sd(result))"), " results out of bounds.")
                           }
) -> results

编辑:

也许试试 myplot() %>% print()。您需要使用 ggplot2.

将绘图实际发送到输出

很抱歉没有早点看到,这才是真正的症结所在:这些图最后出现的原因,根本上是因为它们是 map 函数的输出,所以它们被存储起来by map 全部处理后作为一组输出。

最初的想法:

我经常以类似的方式交错结果。我认为您的问题可能与 "\n"s 不足有关。当正常编写 markdown 时,您会在段落之间留出一行,因此在这里您以编程方式生成的 markdown 必须有 "\n\n" 来指示当前行的结尾和下面的空行。这也适用于情节之后和结果之后。