In an rmarkdown
document, I'm plotting several plots inside a single chunk. I'd like to make the height of each plot proportional to the number of categories on the vertical axis. Based on this SO answer, I'm trying to do this using knit_expand
to create a new chunk for each plot with the chunk options set programmatically.
A sample rmarkdown
document with reproducible data and code is pasted in below. The kexpand
function is what creates a new chunk for each plot. I run the function in a for loop in the last chunk. The for loop creates three plots, one for each level of dept
in the sample data. However, when I (attempt to) knit the document, I get the following error:
Line 23 Error in parse_block(g[-1], g[1], params.src) : duplicate label 'English' Calls: ... process_file -> split_file -> lapply -> FUN -> parse_block Execution halted
This is the first time I've tried to dynamically change chunk options and I'm not sure how a chunk label is getting duplicated, since each level of dept
goes into knit_expand
only once. I tried the suggestion in this SO question to use knit_child
instead of knit
inside the kexpand
function, but I got the same error.
So, my questions are: (1) how can I avoid the duplicate label error and get the document to knit properly, and (2) am I going about this the right way or is there a better way to dynamically change chunk options when creating plots or tables within a loop?
---
title: "Untitled"
author: "eipi10"
date: "February 12, 2017"
output: pdf_document
---
```{r setup, include=FALSE}
knitr::opts_knit$set(progress = FALSE, verbose = FALSE)
knitr::opts_chunk$set(echo = FALSE, message=FALSE, warning=FALSE)
library(tidyverse)
library(scales)
library(knitr)
```
```{r}
# Adapted from https://stackoverflow.com/a/27234462/496488
kexpand <- function(ht, cap, plot) {
cat(
knit(
text=knit_expand(
text=sprintf("```{r %s, fig.height=%s, fig.cap='%s'}\n%s\n```", cap, ht, cap, plot)
)))
}
```
```{r data}
df = structure(list(dept = c("English", "English", "English", "English",
"English", "English", "English", "English", "English", "English",
"English", "English", "English", "English", "English", "Biology",
"Biology", "Biology", "Biology", "Biology", "Biology", "Government",
"Government"), tot_enrl = c(114, 349, 325, 393, 415, 401, 166,
117, 302, 267, 256, 224, 481, 295, 122, 410, 478, 116, 278, 279,
238, 142, 145), course = c("ENGL 1", "ENGL 10M", "ENGL 11M",
"ENGL 16", "ENGL 1X", "ENGL 20M", "ENGL 3", "ENGL 30A", "ENGL 40A",
"ENGL 40B", "ENGL 50A", "ENGL 50B", "ENGL 5M", "ENGL 60", "ENGL 65",
"BIO 15L", "BIO 2", "BIO 30", "BIO 39", "BIO 7", "BIO 9", "GOVT 10",
"GOVT 1H")), class = c("tbl_df", "tbl", "data.frame"), row.names = c(NA,
-23L), .Names = c("dept", "tot_enrl", "course"))
```
```{r results="asis"}
height.unit = 0.2
for (d in unique(df$dept)) {
.pl = ggplot(df[df$dept==d, ], aes(tot_enrl, reorder(course,tot_enrl))) + geom_point()
ht = height.unit * length(unique(df$course[df$dept==d])) + 1
kexpand(ht=ht, cap=d, plot=.pl)
}
```