17

I would like to create a loop, which allows me to automatically save PDF reports, which were generated from a .Rmd file. For instance, if a variable "ID" has 10 rows, I would like R to automatically save me 10 reports, into a specific directory. These reports shall vary based on the ID selected.

A previous post (Using loops with knitr to produce multiple pdf reports... need a little help to get me over the hump) has dealt with the creation of multiple pdf reports generated from .Rnw files. I tried to apply the approach as follows:

#Data

```{r, include=FALSE}
set.seed(500)
Score <- rnorm(40, 100, 15)
Criteria1<-rnorm(40, 10, 5)
Criteria2<-rnorm(40, 20, 5)
ID <- sample(1:1000,8,replace=T)
df <- data.frame(ID,Score,Criteria1,Criteria2)

#instead of manually choosing the ID:

subgroup<- subset(df, ID==1) 

# I would like to subset the Data through a loop. My approach was like like this:

for (id in unique(df$ID)){
subgroup<- df[df$ID == id,]}

```

```{r, echo=FALSE}
#Report Analysis

summary(subgroup)
```
#Here will be some text about the summary.



# At the end the goal is to produce automatic pdf reports with the ID name as a filename:

library("rmarkdown")
render("Automated_Report.rmd",output_file = paste('report.', id, '.pdf', sep=''))
Community
  • 1
  • 1
user3491036
  • 185
  • 1
  • 5
  • 1
    You need one loop, not two. The way your code is set up, you loop through all your subgroups, and then when you're done with that you create a bunch of PDFs. You need to combine these: select a subgroup and create a report based on it all within the same loop. If you need more help, you'll have to be a lot more specific than "seems not be working" and probably create a reproducible example. – Gregor Thomas May 27 '15 at 19:32
  • You could also look at `knit_expand` or the `brew` package. – Gregor Thomas May 27 '15 at 19:34
  • I have also tried it with only one loop for the subsetting. But that didn't work either. I provided a simple reproducible example, which only pastes the summary for each ID in a report and also exchanged the knit2pdf() function with the render() function from the rmarkdown package.@Gregor – user3491036 May 28 '15 at 09:45

1 Answers1

21

Adapting your example:

You need one .rmd "template" file. It could be something like this, save it as template.rmd.

This is a subgroup report.

```{r, echo=FALSE}
#Report Analysis
summary(subgroup)
```

Then, you need an R script that will load the data you want, loop through the data subsets, and for each subset

  1. Define the subgroup object used inside the template
  2. render the template to the desired output

So, in this separate script:

# load data 
set.seed(500)
Score <- rnorm(40, 100, 15)
Criteria1<-rnorm(40, 10, 5)
Criteria2<-rnorm(40, 20, 5)
ID <- sample(1:1000,8,replace=T)
df <- data.frame(ID,Score,Criteria1,Criteria2)

library("rmarkdown")

# in a single for loop
#  1. define subgroup
#  2. render output
for (id in unique(df$ID)){
    subgroup <- df[df$ID == id,]
    render("template.rmd",output_file = paste0('report.', id, '.html'))    
}

This produced 8 html files in my working directory, each with a summary of a different subset of the data.

Note that this will not work if you try clicking the "knit" button inside RStudio, as that runs the R code in a separate R session. However, when you run from the console explicitly using render (or knit2pdf) the R code in the rmd file still has access to the global environment.

Rather than relying on global variables, another option would be to use parametrized reports, defining parameters in the YAML header, and passing the parameter values in as arguments to rmarkdown::render.

Gregor Thomas
  • 136,190
  • 20
  • 167
  • 294
  • Thanks @Gregor this worked! l guess you chose .html because .pdf created an error based on the pandoc output of summary. Since this was anyway just a simple example it did not make a difference in the end. – user3491036 May 28 '15 at 18:51
  • Yup, I figured this would be good to work out the general principles, and the details of content would follow easily. – Gregor Thomas May 28 '15 at 18:54