1

I want to produce multiple graphs and save them on multiple pdf files based. These graphs are different based on a certain category. With this code, it works when producing 1 pdf file

---
output: pdf_document
---

```{r setup, include=FALSE}  

i <- "30-40"

## Packages
library(tidyverse)
library(knitr)
library(rmarkdown)
library(tinytex)
library(readxl)
library(data.table)
library(lubridate)


# Create random data 
ID            <- sample(seq(from = 1, to = 20, by = 1),  100, replace = TRUE)
Date          <- sample(seq(ymd("2019-01-01"), today(), by="day"), 100, replace = TRUE)
Age           <- sample(c("20", "20-30", "30-40", "40-50", "50-60", "60-70", "70+"), 
                        size = 100, 
                        replace = TRUE, 
                        prob=c(0.05, 0.1, 0.075, 0.15, 0.2, 0.175, 0.25))
Duration_call <- sample(seq(from = 30, to = 600, by = 5),  100, replace = TRUE) 
Question      <- sample(c("Question1", "Question2", "Question3", "Question4"), 100, replace = TRUE)


sample_data <- tibble(ID, Date, Age, Duration_call, Question)



```

```{r}
KPI_3 <- sample_data %>%
       filter(Age == i) %>%

       mutate(Maand = lubridate::day(Date)) %>%
       group_by(Maand, Question) %>%
       summarize(Aantal_calls = n()) %>%

       ggplot(aes(Maand, Aantal_calls, group = Question, color = Question)) +
       geom_line()
```

However, if I use this script in order to loop over the different categories (and thus produce different pdf files), it won't work. Note: when using summary statistics (and indenting them into the rmd file), the exact code does work.

## Packages
library(tidyverse)
library(knitr)
library(rmarkdown)
library(tinytex)
library(readxl)
library(data.table)


# Create random data 
ID            <- sample(seq(from = 1, to = 20, by = 1),  100, replace = TRUE)
Date          <- sample(seq(ymd("2019-01-01"), today(), by="day"), 100, replace = TRUE)
Age           <- sample(c("20", "20-30", "30-40", "40-50", "50-60", "60-70", "70+"), 
                        size = 100, 
                        replace = TRUE, 
                        prob=c(0.05, 0.1, 0.075, 0.15, 0.2, 0.175, 0.25))
Duration_call <- sample(seq(from = 30, to = 600, by = 5),  100, replace = TRUE) 
Question      <- sample(c("Question1", "Question2", "Question3", "Question4"), 100, replace = TRUE)


sample_data <- tibble(ID, Date, Age, Duration_call, Question)



# For loop
for (i in unique(sample_data$Age)) {

  print(i)

  rmarkdown::render(input = "Child_script_1.Rmd", # must match RMD 
                    output_format = "pdf_document",
                    output_file = paste("Age", i, ".pdf", sep=''), 
                    output_dir = "MAP")
}

Does someone have any suggestions? Any help would be much appreciated!

Liri
  • 350
  • 3
  • 19
  • Shouldn't you be passing your in-loop `i` as an [rmarkdown parameter](https://bookdown.org/yihui/rmarkdown/parameterized-reports.html)? I would suspect that the `i` declared in your `.Rmd` file would always override what you have in your in-loop environment. (Side note: having an Rmd *rely* on variables not declared explicitly (e.g., in the `setup` chunk) or passed via `params` is a breach of scope and renders documents less-reproducible and (as you can see now) difficult to troubleshoot. Recommendation: treat it like a function, only use variables declared or passed to it explicitly.) – r2evans Oct 02 '19 at 14:14
  • Check out what this person does, it produces in the same document. Is this what you're looking for? https://stackoverflow.com/questions/57034529/create-rmarkdown-chuncks-in-a-loop – Corey Pembleton Oct 02 '19 at 14:19
  • @ r2evans I need to use the rmarkdown paramaters indeed. However, with calculating summary statistics it works perfectly, so I was wondering why it doesn't work when indenting different ggplot visualisations. – Liri Oct 02 '19 at 14:35

1 Answers1

1

If I understand correctly, you need to set the parameter in your markdown YAML document:

In this example, it's taking the produced images (e.g. graphs) created from the output

---
title: "Title"
mainfont: Arial
output:
    pdf_document:
      latex_engine: xelatex
      fig_caption: false
      fig_height: 4
geometry: margin=.5in
params:
    images_params: !r list.files(path = "./images/", pattern = "\\.jpg$", full.names = TRUE)
    data: mtcars
---

and in your Markdown, specify where you want the image in

knitr::include_graphics(params$images_params) #calls on the param

and have another script running it:

plotting_function <- function(df) {


  split_df <- split(df, df$Question)

  names <- names(split_df)

  plots <- map2(split_df, names, 
                ~ggplot(.x, aes(x = Age,
                                y = Duration_call)) +
                          geom_point()

  )

}

reports <- plotting_function(sample_data)


reports %>% pwalk(rmarkdown::render, 
                  input = "./path/Report.Rmd",
                  "pdf_document", envir = new.env())

Which will create a new pdf, with the image inserted where you specify.

I wrote about the process a bit here:

Corey Pembleton
  • 717
  • 9
  • 23
  • If I understand correctly, you are using the `knitr::include_graphics` to indent images which are already produced (and saved) on a local machine. If that is the case, it isn't exactly what I'm looking for. I need to loop (or map over) all the different categories and produce a graph (and pdf) for every one of the plots. Will your piece of code work of do I have to make some adjustments? Thanks in advance. By the way, your method seems very useful! I'm going to read the process on your blog later on. – Liri Oct 02 '19 at 14:33
  • To do that, you can skip the saving part, and in your script just have the code that makes the plot, and have it loop through each plot to render (same as saving to local, but keeping as object instead). I'll update the top part to show how that would look – Corey Pembleton Oct 02 '19 at 14:38
  • I'm going to try it once again with the updated code. Thanks in advance! – Liri Oct 02 '19 at 14:43
  • That doesn't exactly address your challenge, you're going to need to play with the parameter settings because it's not pulling the jpg anymore. But essentially it's the same, but saving the code as an object, and feeding that list into your pwalk call. – Corey Pembleton Oct 02 '19 at 14:46