Background: Using Purrr to filter a dataset and plot a series of graphs using ggplot (in RMarkdown, for Shiny)
Following the resolution of the previous question, above, I now have a .Rmd file that will produce a Word document with section headers, graphs, and a table of contents.
The following problems remain:
- The section headers and graphs are not interleaved. What I currently have is:
header1
header2
header3
graph1
graph2
graph3
How should my code be amended to produce:
header1
graph1
header2
graph2
header3
graph3
instead?
The word document includes numbers in square brackets, e.g. "[[1]]", "[[2]]", etc, which I believe get printed with the graphs. How can these be removed?
For each graph I'd like a boilerplate sentence that includes a statement about the data, specifically the number of datapoints that lie outside the dotted lines +/- 2SD from the mean. I've tried adding it by including e.g.
report.data %>%
dplyr::filter(identifier == x) %>%
paste(eval("r sum(result < mean(result) - 2 * sd(result))"), " results out of bounds.")
in the function, but this turns the graphs into text(!).
As always, any help or advice that can be offered would be greatly appreciated - thank you for reading!
Script to generate example data and produce the report:
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")
The report.Rmd file:
---
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.")
}
)
```
EDIT: the current version of the code for the map function, following Sean van der Merwe's kind advice, below:
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