I managed to create a html document that creates dynamic tabsets based on a list of items. Adding one plot works fine on one tabset. How can I add now multiple plots on one tabset?
Hereby the code I started from but it only shows 1 plot per tabset when you knit the document to html output. obviously there is still something missing.
---
title: "R Notebook"
output:
html_document:
df_print: paged
editor_options:
chunk_output_type: inline
---
### header 1
```{r}
library(ggplot2)
df <- mtcars
pl_list <- list()
pl1 <- qplot(cyl, disp, data = df[1:12,])
pl2 <- qplot(mpg, cyl, data = df[13:20,])
pl3 <- qplot(mpg, cyl, data = df[21:30,])
pl4 <- qplot(mpg, cyl, data = df[1:12,])
pl_list[[1]] <- list(pl1, pl3, "one")
pl_list[[2]] <- list(pl2, pl4, "two")
```
### header {.tabset}
```{r, results = 'asis', echo = FALSE}
for (i in seq_along(pl_list)){
tmp <- pl_list[[i]]
cat("####", tmp[[3]], " \n")
print(tmp[1])
cat(" \n\n")
}
```
There are a couple of improvements you can do.
Create cat header function with arguments for text and level.
With it you don't need to call cat multiple times and it creates wanted number of # automatically.
catHeader <- function(text = "", level = 3) {
cat(paste0("\n\n",
paste(rep("#", level), collapse = ""),
" ", text, "\n"))
}
print plots using lapply.
Full code looks like this:
---
title: "R Notebook"
output:
html_document:
df_print: paged
editor_options:
chunk_output_type: inline
---
```{r, functions}
catHeader <- function(text = "", level = 3) {
cat(paste0("\n\n",
paste(rep("#", level), collapse = ""),
" ", text, "\n"))
}
```
### header 1
```{r}
library(ggplot2)
df <- mtcars
pl_list <- list()
pl1 <- qplot(cyl, disp, data = df[1:12,])
pl2 <- qplot(mpg, cyl, data = df[13:20,])
pl3 <- qplot(mpg, cyl, data = df[21:30,])
pl4 <- qplot(mpg, cyl, data = df[1:12,])
pl_list[[1]] <- list(pl1, pl3, "one")
pl_list[[2]] <- list(pl2, pl4, "two")
```
## header {.tabset}
```{r, results = "asis", echo = FALSE}
for(i in seq_along(pl_list)){
tmp <- pl_list[[i]]
# As you want to use tabset level here has to be lower than
# parent level (ie, parent is 2, so here you have to use 3)
catHeader(tmp[[3]], 3)
lapply(tmp[1:2], print)
}
```
Related
I would like to automatically generate R markdown chunks and headings within a for loop in R for a list of data.frames which varies length depending on input. These are then the input for plot generation. This R markdown document will then be knitted to a html_document using the package knitr.
I have attempted the solutions from several similar SO questions which can get me close, but is not what I actually need:
https://stackoverflow.com/a/44671368/10771401
https://stackoverflow.com/a/57034752/10771401
The problem is that I have 4 chunks that I'd like to repeat where each chunk has to have different chunk options (fig.width, fig.height) to correctly display the ggplot2 objects in them. So, I can't simply just supply a single set of options in the code chunk itself).
Here is an example of one of my failed attempts (NOTE: the second code block below also contains a comment indicating the chunk options which is required):
# Chunk data demo
data_list <- list(a=data.frame(), b=data.frame(), c=data.frame())
plot_1 <- list()
plot_2 <- list()
for (i in 1:length(data_list)) {
data_list[[i]] <- data.frame(x = 1:5, y = 1:5)
plot_1[[i]] <- ggplot(data_list[[i]], aes(x, y)) + geom_point()
plot_2[[i]] <- ggplot(data_list[[i]], aes(x, y)) + geom_point()
}
#```{r, results='asis'} (Start of R markdown chunk)
# Chunk generation (only 2 chunks are written for brevity)
for (i in 1:length(data_list)) {
# Section heading
cat("\n\n")
cat("##", names(data_list)[i])
# Chunk 1 ----
cat("\n\n")
cat("### Sub-section 1")
cat("\n\n")
cat("**Title 1**")
cat("\n\n")
cat('```{r, fig.width=10, fig.height=10}')
cat("\n\n")
print(plot_1[[i]])
cat("\n\n")
cat('```')
# Chunk 2 ----
cat("\n\n")
cat("### Sub-section 2")
cat("\n\n")
cat("**Title 2**")
cat("\n\n")
cat('```{r, fig.width=10, fig.height=3}') # NOTE: Change in option
cat("\n\n")
print(plot_2[[i]])
cat("\n\n")
cat('```')
cat("\n\n")
}
#``` (End of R markdown chunk)
EDIT: Removed the ggsave() calls, as not necessary to illustrate the problem which is apparent in the knitted document.
I see what you are trying to do, and I think the approach you are taking won't work. (But I guess you already knew that!) Here's why:
When you run the asis chunk, you are producing Markdown, not R Markdown. The fig.width and fig.height options need to be handled by knitr when it is processing R Markdown, but that only happens once. The next stage of processing which handles the Markdown is done by Pandoc, and it doesn't know anything about fig.width and fig.height.
So what you need to do is to produce a "child document", then get knitr to include it in your main document. Those are described here: https://bookdown.org/yihui/rmarkdown-cookbook/child-document.html . Basically they are just fragments of R Markdown to include in your main document. Here's a modification of your document that does this:
---
title: "Untitled"
author: "Duncan Murdoch"
date: "2023-02-12"
output:
html_document:
keep_md: true
---
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
```
## R Markdown
```{r}
library(ggplot2)
# Create the plots
data_list <- list(a=data.frame(), b=data.frame(), c=data.frame())
plot_1 <- list()
plot_2 <- list()
for (i in 1:length(data_list)) {
data_list[[i]] <- data.frame(x = 1:5, y = 1:5)
plot_1[[i]] <- ggplot(data_list[[i]], aes(x, y)) + geom_point()
plot_2[[i]] <- ggplot(data_list[[i]], aes(x, y)) + geom_point()
}
```
```{r echo = FALSE}
# Create a child document
child <- "child.Rmd"
cat("\n", file = child)
# Save typing file = child, append = TRUE every time
# by making a new function to call cat
cat2 <- function(...) cat(..., file = child, append = TRUE)
for (i in 1:length(data_list)) {
# Section heading
cat2("\n\n")
cat2("##", names(data_list)[i])
# Chunk 1 ----
cat2("\n\n")
cat2("### Sub-section 1")
cat2("\n\n")
cat2("**Title 1**")
cat2("\n\n")
cat2('```{r fig.width=10, fig.height=10}')
cat2("\n\n")
cat2("i = ", i, "\n")
cat2("print(plot_1[[i]])")
cat2("\n\n")
cat2('```')
# Chunk 2 ----
cat2("\n\n")
cat2("### Sub-section 2")
cat2("\n\n")
cat2("**Title 2**")
cat2("\n\n")
cat2("```{r fig.width=10, fig.height=3}")
cat2("\n\n")
cat2("print(plot_2[[i]])")
cat2("\n\n")
cat2('```')
cat2("\n\n")
}
```
```{r child="child.Rmd"}
```
You can also use the knitr::knit_expand() and pass it to the knitr::knit_child() function.
Edit:
---
output: html_document
---
```{r, echo=FALSE, results='asis'}
library(purrr)
library(ggplot2)
data_list <- list(a=data.frame(x = 1:5, y = 1:5), b=data.frame(x = 1:5, y = 1:10), c=data.frame(x = 1:5, y = 1:15))
data_plots_1 <- map(data_list, ~ggplot(.x, aes(x, y)) + geom_point())
data_plots_2 <- map(data_list, ~ggplot(.x, aes(x, y)) + geom_point(color = "red"))
fig_width <- c(7,5,5)
fig_height <- c(5,3,3)
data_names <- data_list %>% names()
```
```{r results='asis', echo=FALSE}
structure_text <- purrr::pmap_chr(list(data_names, fig_width, fig_height), \(data_names, fig_width, fig_height) {
knitr::knit_expand(text = c(
"## Title Plot 1 dataset {{data_names}}",
"",
"",
"```{r, fig.width= {{ fig_width }}, fig.height= {{ fig_height }}, echo =FALSE }",
"data_plots_1${{data_names}} ",
"```",
"",
"## Title Plot 2 dataset {{data_names}}",
"",
"",
"```{r, fig.width= {{ fig_width }}, fig.height= {{ fig_height }}, echo =FALSE }",
"data_plots_2${{data_names}} ",
"```",
""
))
})
res <- knitr::knit_child(text = structure_text, quiet = TRUE)
cat(res, sep = '\n')
Old
---
output: html_document
---
```{r, echo=FALSE, results='asis'}
library(purrr)
library(ggplot2)
data_list <- list(a=data.frame(x = 1:5, y = 1:5), b=data.frame(x = 1:5, y = 1:10))
data_names <- data_list %>% names()
fig_width <- c(7,5)
fig_height <- c(5,3)
```
```{r results='asis', echo=FALSE}
structure_text <- purrr::pmap_chr(list(data_names, fig_width, fig_height), \(data_names, fig_width, fig_height) {
knitr::knit_expand(text = c(
"## {{ data_names }}",
"",
"",
"```{r, fig.width= {{ fig_width }}, fig.height= {{ fig_height }}, echo =FALSE }",
"data_list${{data_names}} |>",
" ggplot(aes(x = x, y = y)) +",
" geom_point()",
"```",
""))
})
res <- knitr::knit_child(text = structure_text, quiet = TRUE)
cat(res, sep = '\n')
I am new to shiny/flexdashboard and so far have been able to render plots and filter dataframe by using values from selectInput with help of req(input$user_input_value) .
ISSUE: To run kmeans I am taking user input for number of clusters which I am not able to code it in reactive format and getting error: object of type closure is not subsettable.
```{r setup, include=FALSE}
library(flexdashboard)
library(shiny)
library(tidyverse)
library(tidytext)
library(scales)
library(glue)
library(widyr)
library(factoextra)
```
df
1 2 3 4
Angola -0.08260540 0.034325891 -0.02013353 -0.014063951
Armenia -0.06613693 -0.044308626 -0.13230387 -0.024534033
Azerbaijan -0.07562365 -0.003670707 0.05886792 -0.219660410
Bahrain -0.08275891 0.035843793 -0.02280102 -0.008044934
Bangladesh -0.08306371 0.032998297 -0.02634819 -0.017627316
Bosnia & Herzegovina -0.06303898 -0.050781511 -0.15183954 0.016794674
(Note: I have placed the csv file in github & mentioned its link below. For kmeans the character column should be used as rownames which represents country here.)
UPDATED df CREATION STEP
svd_dimen_all_wide <- read.csv(url("https://raw.githubusercontent.com/johnsnow09/covid19-df_stack-code/main/svd_dimen_all_wide.csv"))
svd_dimen_all_wide <- as.data.frame(svd_dimen_all_wide)
rownames(svd_dimen_all_wide) <- svd_dimen_all_wide$X
svd_dimen_all_wide <- svd_dimen_all_wide[,2:ncol(svd_dimen_all_wide)]
flexdashboard
---
title: "UN Country Votes"
output:
flexdashboard::flex_dashboard:
orientation: columns
vertical_layout: fill
theme: space
runtime: shiny
---
```{r setup, include=FALSE}
library(flexdashboard)
library(shiny)
library(tidyverse)
library(tidytext)
library(scales)
library(glue)
library(widyr)
library(factoextra)
Page NAme
=====================================
Inputs {.sidebar}
-----------------------------------------------------------------------
```{r}
selectInput("number_of_clusters", label = h3("Number of Clusters"),
choices = c(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15) ,
selected = 6)
```
Column {data-width=1000}
-----------------------------------------------------------------------
```{r include=FALSE}
set.seed(123)
km.res <- reactive({
# req(input$number_of_clusters)
kmeans(svd_dimen_all_wide, as.numeric(input$number_of_clusters), nstart = 25)
})
df_with_cluster <- cbind(svd_dimen_all_wide, cluster = km.res$cluster)
df_with_cluster <- rownames_to_column(df_with_cluster, "country")
df_with_cluster <- df_with_cluster %>%
select(country, cluster, everything())
```
UPDATED ATTEMPT:
renderPrint({
df_with_cluster <- cbind(svd_dimen_all_wide, cluster = km.res()$cluster)
df_with_cluster <- rownames_to_column(df_with_cluster, "country")
df_with_cluster <- df_with_cluster %>%
select(country, cluster, everything())
head(df_with_cluster)
})
### Comparison of Countries on Yes% of Bi Words
```{r}
renderPlot({
world_data %>%
left_join((df_with_cluster %>%
mutate(country_code = countrycode(country, "country.name", "iso2c"))
),
by = c("country_code")) %>%
filter(!is.na(cluster)) %>%
ggplot(aes(x = long, y = lat, group = group,
fill = as.factor(cluster))) +
geom_polygon() +
theme_map() +
scale_fill_discrete() +
labs(fill = "cluster",
title = "World Clusters based on UN voting",
caption = "created by ViSa") +
theme(plot.title = element_text(face = "bold", size = 16))
})
```
The problem is in a reactive chunk. The reactive expression km.res uses an input number of clusters, runs a model, and saves the output. (and let's end the code chunk here).
Next, decide what do you want to do with the output?
to print the result, use renderPrint
to show as a plot, use renderPlot,
to show as a table, user renderTable, etc.
Now Let's print the output of the model with renderPrint() the output can be accessed by calling the expression’s name followed by parenthesis, e.g., km.res()
Column {data-width=1000}
-----------------------------------------------------------------------
```{r include=FALSE}
km.res <- reactive({
req(input$number_of_clusters)
set.seed(123)
kmeans(svd_dimen_all_wide, as.numeric(input$number_of_clusters), nstart = 25)
})
```
###
```{r model}
renderPrint({
df_with_cluster <- cbind(svd_dimen_all_wide, cluster = km.res()$cluster)
head(df_with_cluster)
})
```
Here is my blog post very relevant to this problem https://towardsdatascience.com/build-an-interactive-machine-learning-model-with-shiny-and-flexdashboard-6d76f59a37f9?sk=922526470699966c3f47b24843404a15
I'm trying to build a report dynamically that requires running a loop, and for each iteration printing some messages, tables, and a plot. I can get everything to work except for the plot.
example.rmd
```{r echo=FALSE, results='asis', fig.keep='all', message = FALSE, warning = FALSE}
library(knitr)
library(plotly)
for(i in 1:4){
foo <- iris[sample(nrow(iris), 20), ]
cat("\n")
cat("# Iteration", i, "\n")
# Print the first few lines
print(kable(head(foo)))
cat("\n")
# Plot Sepal.Width vs Petal.Length using ggplotly()
plt <- ggplot(foo, aes(x = Sepal.Width, y = Petal.Length))+geom_point()
# plot(plt) # <- this works
# plot(ggplotly(plt)) # <- this doesn't work
# ggplotly(plt) # <- this doesn't work
cat("\n")
}
```
How can I get the plotly plots to render in my report?
Following this post on github about basically the same issue, I was able to put together this very hacky solution. Would love to find a better method.
```{r echo=FALSE, results='asis', fig.keep='all', message = FALSE, warning = FALSE}
library(knitr)
library(plotly)
# Build list of outputs
output <- list()
for(i in 1:4){
foo <- iris[sample(nrow(iris), 20), ]
# Header for iteration
txt <- paste0("#Iteration ", i)
output[[length(output) + 1L]] <- txt
# Table of the first few lines
tbl <- kable(head(foo))
output[[length(output) + 1L]] <- tbl
# Plot
plt <- ggplotly(ggplot(foo, aes(x = Sepal.Width, y = Petal.Length))+geom_point())
output[[length(output) + 1L]] <- plt
}
# Render the outputs
for(j in 1:length(output)){
x <- output[[j]]
if(inherits(x, "character")){
cat("\n")
cat(x)
} else if(inherits(x, "knitr_kable")){
cat("\n")
print(x)
}
else {
# print the html piece of the htmlwidgets
cat("\n")
cat(htmltools::renderTags(as.widget(x))$html)
}
}
```
```{r echo=FALSE, messages=FALSE, warning=FALSE}
# Attach the Dependencies since they do not get included with renderTags(...)$html
deps <- lapply(
Filter(f = function(x){inherits(x,"htmlwidget")}, x = output),
function(hw){
htmltools::renderTags(hw)$dependencies
}
)
htmltools::attachDependencies(x = htmltools::tagList(), value = unlist(deps,recursive=FALSE))
```
I am trying to create a table in RMarkdown that looks similar to the following example:
---
title: "Example"
output: pdf_document
---
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = FALSE)
```
```{r cars, echo=FALSE, message=FALSE, warning=FALSE, results='asis'}
library(Hmisc)
latex(mtcars, file = "", cgroup = c("mpg", "cyl"), n.cgroup = c(1,10))
```
I would like to group columns 2 through 10. Any ideas on how I can accomplish this with the Hmisc package or any other R package?
I think just using a blank header name for the first column gives you what you want:
latex(mtcars, file = "", cgroup = c("", "cyl"), n.cgroup = c(1,10))
Result:
Using my package:
library(huxtable)
hux_cars <- as_hux(mtcars, add_colnames = TRUE)
hux_cars <- insert_row(hux_cars, c('mtcars', 'cyl', rep('', 9)))
colspan(hux_cars)[1, 2] <- 10
align(hux_cars)[1, 2] <- 'centre'
bold(hux_cars)[1, ] <- TRUE
position(hux_cars) <- 'left'
quick_pdf(hux_cars)
Which produces:
{r setup, include=FALSE, message=FALSE, results="hide"}
knitr::opts_chunk$set(echo = TRUE)
library(knitr)
library(kfigr)
library(dplyr)
library(png)
library(grid)
library(pander)
library(ggplot2)
Question
Loops in rmarkdown: in-text figure reference? figure captions?
Goal
Use a for loop to create sections with text, in-text results, and multiple figure references with associated figure captions in the figure list. The figure references/numbering should be seemless with figures numbered before and after these new sections.
Note: The figures referenced in the for loop are generated earlier in the text, saved as pngs, and then re-loaded. This might seem clunky for the purpose of this example, but the actual figs are maps and are slow to generate (I plan to comment out the loop that generates the figures once I have them how I want).
{r echo = FALSE, warnings=FALSE, message=FALSE, results="hide"}
Data: Each year we have a different number of strata, hence the need for a loop.
df <- rbind(
data.frame(strata = rep("A", 10), x = rnorm(10, mean= 10), y = rnorm(10, mean = 15),z = rnorm(10, mean = 20)),
data.frame(strata = rep("B", 10), x = rnorm(10, mean= 5), y = rnorm(10, mean = 10), z = rnorm(10, mean = 15)),
data.frame(strata = rep("C", 10), x = rnorm(10, mean= 15), y = rnorm(10, mean = 20), z = rnorm(10, mean = 10)))
first_plot: the figure that should appear in the list before for loop creates the sections by strata
first_plot <- ggplot(df, aes(x, fill=strata)) + geom_histogram()
last_plot: the figure that should appear in the list after the for loop creates the sections by strata
last_plot <- ggplot(df, aes(x = strata, y = z)) + geom_boxplot()
Figure generation (this is the part that will be commented out later in my version once I have the maps how I want)
strat <- unique(df$strata)
for (i in seq_along(strat)) {
sub <- df %>% filter(strata %in% strat[i])
fig1 <- ggplot(sub, aes(x = x, y = y)) + geom_point()
ggsave(fig1, file=paste0("fig1_", strat[i], ".png"))
fig2 <- ggplot(sub, aes(x = x, y = z)) + geom_point()
ggsave(fig2, file=paste0("fig2_", strat[i], ".png"))
}
Load the png's
df_figs <- list.files(pattern = "\\.png$")
for (i in df_figs){
name <- gsub("-",".",i)
name <- gsub(".png","",name)
i <- paste(".\\",i,sep="")
assign(name,readPNG(i))
}
Introduction section
Some introductory text in the report and a figure r figr('first_plot',TRUE, type='Figure').
```{r echo = FALSE, warnings=FALSE, message=FALSE, results = "asis"}
# Summary of results and image file names that will be references in text
results <- df %>%
group_by(strata) %>%
dplyr::summarise_each(funs(mean)) %>%
mutate(fig1 = paste0("fig1_", strata),
fig2 = paste0("fig2_", strata))
#Text template (each strata will have its own section)
template <- "# The %s stratum
The mean of *x* in %s stratum was %1.1f. Relationships between *x* and *y* and *x* and *z* can be found in `r figr('%s', TRUE, type='Figure')` and `r figr('%s', TRUE, type='Figure')`.
"
#Create markdown sections in for loop
for(i in seq(nrow(results))) {
current <- results[i, ]
cat(sprintf(template,
current$strata, current$strata,
current$x,
current$fig1, current$fig2))
}
#Also doesn't work:
template <- "# The %s stratum
The mean in %s stratum was %1.0f. Results can be found in "
template2 <- " and "
template3 <- ".
"
`figr('%s', TRUE, type='Figure')` and `figr('%s', TRUE, type='Figure')`."
#For loop
for(i in seq(nrow(results))) {
current <- results[i, ]
cat(sprintf(template,
current$strata, current$strata,
current$mean,
current$fig_1, current$fig_2))
print(paste0("`r figr(",paste0("'", current$fig1,"'"), TRUE, type='Figure'))
cat(sprintf(template2))
print(paste0("`r figr(",paste0("'", current$fig2,"'"), "TRUE, type='Figure'),`"))
cat(sprintf(template3))
}
```
Conclusion section
Some discussion text in the report and figure r figr('last_plot',TRUE, type='Figure').
Figures
*NOTE:* I don't know how to automate the looped portion of the list of figures here, so I've done it by hand.
```{r 'first_plot', echo=FALSE, warning=FALSE, fig.width=6.5, fig.height=6, fig.cap="The caption for the first figure."}
suppressMessages(print(first_plot))
```
```{r 'fig1_A', echo=FALSE, warning=FALSE, fig.width=6.5, fig.height=6, fig.cap="Caption text for fig1_A."}
grid.raster(fig1_A)
```
```{r 'fig2_A', echo=FALSE, warning=FALSE, fig.width=6.5, fig.height=6, fig.cap="Caption text for fig2_A."}
grid.raster(fig2_A)
```
```{r 'fig1_B', echo=FALSE, warning=FALSE, fig.width=6.5, fig.height=6, fig.cap="Caption text for fig1_B."}
grid.raster(fig1_B)
```
```{r 'fig2_B', echo=FALSE, warning=FALSE, fig.width=6.5, fig.height=6, fig.cap="Caption text for fig2_B."}
grid.raster(fig2_B)
```
```{r 'fig1_C', echo=FALSE, warning=FALSE, fig.width=6.5, fig.height=6, fig.cap="Caption text for fig1_C."}
grid.raster(fig1_C)
```
```{r 'fig2_C', echo=FALSE, warning=FALSE, fig.width=6.5, fig.height=6, fig.cap="Caption text for fig2_C."}
grid.raster(fig2_C)
```
```{r 'last_plot', echo=FALSE, warning=FALSE, fig.width=6.5, fig.height=6, fig.cap="The caption for the last figure."}
suppressMessages(print(last_plot))
```
SOLUTIONS
Use knit_expand()
Use captioner instead of kfigr
This numbers your figures (or tables) in text and at the end of your report.
This script shows you how to create markdown paragraphs in for loops that have in-text references to figures.
It also shows you how to create custom figure captions in for loops while retaining the number order.
If you show how to do #4 and #5 using brew I will give you all the SO points.
Libraries
library(knitr)
library(dplyr)
library(png)
library(grid)
library(pander)
library(ggplot2)
library(devtools)
library(captioner)
Create a fig_nums() function using the captioner package
(https://github.com/adletaw/captioner/blob/master/vignettes/using_captioner.Rmd)
fig_nums <- captioner(prefix = "Figure")
Data
Each year we have a different number of strata, hence the need for a loop.
df <- rbind(
data.frame(strata = rep("A", 10), x = rnorm(10, mean= 10), y = rnorm(10, mean = 15), z = rnorm(10, mean = 20)),
data.frame(strata = rep("B", 10), x = rnorm(10, mean= 5), y = rnorm(10, mean = 10), z = rnorm(10, mean = 15)),
data.frame(strata = rep("C", 10), x = rnorm(10, mean= 15), y = rnorm(10, mean = 20), z = rnorm(10, mean = 10)))
first_plot: the figure that should appear in the list before for loop creates the sections by strata
first_plot <- ggplot(df, aes(x, fill=strata)) + geom_histogram()
fig_nums("first_plot", display = FALSE)
last_plot: the figure that should appear in the list after the for loop creates the sections by strata
last_plot <- ggplot(df, aes(x = strata, y = z)) + geom_boxplot()
Figure generation
Comment this section out once you have figs how you want. This step will not feel convoluted, unnatural, suboptimal, unnecessary, or like a very bad idea if you do a lot of mapping in R.
strat <- unique(df$strata)
for (i in seq_along(strat)) {
sub <- df %>% filter(strata %in% strat[i])
fig1 <- ggplot(sub, aes(x = x, y = y)) + geom_point()
ggsave(fig1, file=paste0("fig1_", strat[i], ".png"))
fig2 <- ggplot(sub, aes(x = x, y = z)) + geom_point()
ggsave(fig2, file=paste0("fig2_", strat[i], ".png"))
}
Load the png's
df_figs <- list.files(pattern = "\\.png$")
for (i in df_figs){
name <- gsub("-",".",i)
name <- gsub(".png","",name)
i <- paste(".\\",i,sep="")
assign(name,readPNG(i))
}
Introduction
Some introductory text in the report and a figure r fig_nums("first_plot", display="cite").
Results and image file names that will be referenced in text:
```{r echo = FALSE, warnings=FALSE, message=FALSE, results = "asis"}
results <- df %>%
group_by(strata) %>%
dplyr::summarise_each(funs(mean)) %>%
mutate(fig1 = paste0("fig1_", strata),
fig2 = paste0("fig2_", strata))
```
```{r run-numeric-md, warning=FALSE, include=FALSE}
#The text for the markdown sections in for loop... the knit_expand() is the work-horse here.
out = NULL
for (i in as.character(unique(results$strata))) {
out = c(out, knit_expand(text=c('#### The *{{i}}* strata',
'\n',
'The mean of *x* is ',
'{{paste(sprintf("%1.1f", results$x[results$strata==i]))}}', '({{fig_nums(results$fig1[results$strata==i],display="cite")}}).',
'\n'
)))
}
```
Creates section for each strata
`r paste(knit(text = out), collapse = '\n')`
Conclusion
Some discussion text in the report and figure r fig_nums("last_plot",display="cite").
List of Figures
`r fig_nums("first_plot",caption="Here is the caption for the first figure.")`
```{r 'first_plot', echo=FALSE, warning=FALSE, fig.width=6.5, fig.height=6}
suppressMessages(print(first_plot))
```
```{r figcaps, include=FALSE}
caps = NULL
for (i in as.character(unique(results$strata))) {
caps = c(caps, knit_expand(
text=c({{fig_nums(results$fig1[results$strata==i], caption="Caption text for strata *{{i}}* goes here.")}},
'``` {r {{results$fig1[results$strata==i]}}, echo=FALSE, warning=FALSE, fig.width=6.5, fig.height=6}',
{{paste0('grid.raster(',results$fig1[results$strata==i],')')}},
'```',
'\n')))
}
#DON'T FORGET TO UNLIST!
src <- unlist(caps)
```
`r paste(knit(text = src),sep='\n')`
`r fig_nums("last_plot", caption="The caption for the last figure.")`
```{r 'last_plot', echo=FALSE, warning=FALSE, fig.width=6.5, fig.height=6}
suppressMessages(print(last_plot))
```