Using rmarkdown with many plots created in a loop

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

Using rmarkdown with many plots created in a loop

R help mailing list-2
I would appreciate some suggestions of a good way to prepare a report using rmarkdown,
in which I loop through subsets of a data set, creating a plot of each subset, and interspersing
among the figures some text relevant to each figure.

One way is to have an R script write the rmd file, then render it.
It works, but it's cumbersome and difficult to get the rmd syntax correct.
I would very much appreciate suggestions for a better way.

Reproducible example below.

Thanks
-Don


Example data (other data structures could be used), and an example using this approach.

myd <- lapply( 1:3,
              function(i) list(df=data.frame(x=1:5, y=rnorm(5)),
                               comment=paste('Data', LETTERS[i]))
              )

Example interactive review (details would change depending on data structure)
(I would typically insert pauses when working interactively)

for (i in 1:3) {
  cat(paste('Figure',i,'shows',myd[[i]]$comment),'\n')
  with(myd[[i]]$df , plot(x,y))
  mtext(myd[[i]]$comment)
  mtext( paste(nrow(myd[[i]]$df),'points'), adj=1)
}

Note that along with the data I've saved some comments relevant to each subset.
I've calculated them in the example data, but in general they could be completely
arbitrary and come from anywhere.

Now I'd like to get the same plots and comments into a report prepared using rmarkdown.
Here's one way, having the loop create an rmd file, then rendering it.

### example script begins
library(rmarkdown)

myf <- 'myd.rmd'
sink(myf)
cat('---
title: Example
---

Here are some figures with a comment appearing before each.\n\n'
)
sink()

for (i in 1:3) {
  cat(paste('Figure',i,'comment:',myd[[i]]$comment),'\n', file=myf, append=TRUE)

  cat("
```{r  echo=FALSE, fig.cap='",paste('fig',i),"caption.'}
  with(myd[[",i,"]]$df , plot(x,y))
  mtext(myd[[",i,"]]$comment)
  mtext( paste(nrow(myd[[",i,"]]$df),'points'), adj=1)
```
", file=myf, append=TRUE)
   
}

cat('Done with report\n', file=myf, append=TRUE)

render(myf)

--
Don MacQueen
Lawrence Livermore National Laboratory
7000 East Ave., L-627
Livermore, CA 94550
925-423-1062
Lab cell 925-724-7509
 
 

______________________________________________
[hidden email] mailing list -- To UNSUBSCRIBE and more, see
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
and provide commented, minimal, self-contained, reproducible code.
Reply | Threaded
Open this post in threaded view
|

Re: Using rmarkdown with many plots created in a loop

Thierry Onkelinx
Dear Don,

Have a look at the knit_expand() function. Then you can create two Rmd
files. One main file and one template file for the subsets. knit_expand()
will find and replace anything between double curly brackets ("{{x}}" in
the example below) with the value of the variable.

The main file:

---
title: "main"
output: html_document
---

```{r setup, include=FALSE}
library(knitr)
```

```{r}
mydf <- data.frame(
  id = 1:4,
  x = rnorm(100),
  y = rnorm(100)
)
```

```{r}
rmd <- sapply(
  1:4,
  function(x) {
    knit_expand("child.Rmd", x = x)
  }
)
rmd <- paste(rmd, collapse = "\n")
cat(rmd)
```
```{r results = "asis"}
rendered <- knit(text = rmd, quiet = TRUE)
cat(rendered, sep = "\n")
```


The child.Rmd file

## ID {{x}}

```{r, fig.cap = "The caption: ID = {{x}}", echo = FALSE}
i <- {{x}}
detail <- subset(mydf, id == i)
plot(x ~ y, data = detail)
```

Best regards,


ir. Thierry Onkelinx
Statisticus / Statistician

Vlaamse Overheid / Government of Flanders
INSTITUUT VOOR NATUUR- EN BOSONDERZOEK / RESEARCH INSTITUTE FOR NATURE AND
FOREST
Team Biometrie & Kwaliteitszorg / Team Biometrics & Quality Assurance
[hidden email]
Havenlaan 88 bus 73, 1000 Brussel
www.inbo.be

///////////////////////////////////////////////////////////////////////////////////////////
To call in the statistician after the experiment is done may be no more
than asking him to perform a post-mortem examination: he may be able to say
what the experiment died of. ~ Sir Ronald Aylmer Fisher
The plural of anecdote is not data. ~ Roger Brinner
The combination of some data and an aching desire for an answer does not
ensure that a reasonable answer can be extracted from a given body of data.
~ John Tukey
///////////////////////////////////////////////////////////////////////////////////////////

<https://www.inbo.be>

2018-08-17 1:44 GMT+02:00 MacQueen, Don via R-help <[hidden email]>:

> I would appreciate some suggestions of a good way to prepare a report
> using rmarkdown,
> in which I loop through subsets of a data set, creating a plot of each
> subset, and interspersing
> among the figures some text relevant to each figure.
>
> One way is to have an R script write the rmd file, then render it.
> It works, but it's cumbersome and difficult to get the rmd syntax correct.
> I would very much appreciate suggestions for a better way.
>
> Reproducible example below.
>
> Thanks
> -Don
>
>
> Example data (other data structures could be used), and an example using
> this approach.
>
> myd <- lapply( 1:3,
>               function(i) list(df=data.frame(x=1:5, y=rnorm(5)),
>                                comment=paste('Data', LETTERS[i]))
>               )
>
> Example interactive review (details would change depending on data
> structure)
> (I would typically insert pauses when working interactively)
>
> for (i in 1:3) {
>   cat(paste('Figure',i,'shows',myd[[i]]$comment),'\n')
>   with(myd[[i]]$df , plot(x,y))
>   mtext(myd[[i]]$comment)
>   mtext( paste(nrow(myd[[i]]$df),'points'), adj=1)
> }
>
> Note that along with the data I've saved some comments relevant to each
> subset.
> I've calculated them in the example data, but in general they could be
> completely
> arbitrary and come from anywhere.
>
> Now I'd like to get the same plots and comments into a report prepared
> using rmarkdown.
> Here's one way, having the loop create an rmd file, then rendering it.
>
> ### example script begins
> library(rmarkdown)
>
> myf <- 'myd.rmd'
> sink(myf)
> cat('---
> title: Example
> ---
>
> Here are some figures with a comment appearing before each.\n\n'
> )
> sink()
>
> for (i in 1:3) {
>   cat(paste('Figure',i,'comment:',myd[[i]]$comment),'\n', file=myf,
> append=TRUE)
>
>   cat("
> ```{r  echo=FALSE, fig.cap='",paste('fig',i),"caption.'}
>   with(myd[[",i,"]]$df , plot(x,y))
>   mtext(myd[[",i,"]]$comment)
>   mtext( paste(nrow(myd[[",i,"]]$df),'points'), adj=1)
> ```
> ", file=myf, append=TRUE)
>
> }
>
> cat('Done with report\n', file=myf, append=TRUE)
>
> render(myf)
>
> --
> Don MacQueen
> Lawrence Livermore National Laboratory
> 7000 East Ave., L-627
> Livermore, CA 94550
> 925-423-1062
> Lab cell 925-724-7509
>
>
>
> ______________________________________________
> [hidden email] mailing list -- To UNSUBSCRIBE and more, see
> https://stat.ethz.ch/mailman/listinfo/r-help
> PLEASE do read the posting guide http://www.R-project.org/
> posting-guide.html
> and provide commented, minimal, self-contained, reproducible code.
>

        [[alternative HTML version deleted]]

______________________________________________
[hidden email] mailing list -- To UNSUBSCRIBE and more, see
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
and provide commented, minimal, self-contained, reproducible code.
Reply | Threaded
Open this post in threaded view
|

Re: Using rmarkdown with many plots created in a loop

Richard M. Heiberger
In reply to this post by R help mailing list-2
## Don,

## This is how I would approach the task of a set of coordinated plots.
## I would place individual plots inside a table.  The rows would index the
## datasets and there would be one or more data or description columns
## in addition to the column containing the graphs.

## I use the microplot package that I placed on CRAN about two years ago.

## install.packages("microplot") ## if necessary


library(microplot)
latexSetOptions()

## I normally use lattice.  microplot also works with ggplot or base graphics
library(lattice)

## I placed your data into a single data.frame
myd <- lapply( 1:3,
              function(i) list(df=data.frame(x=1:5, y=rnorm(5)),
                               comment=paste('Data', LETTERS[i]))
              )

mydf <- cbind(group=rep(c("A", "B", "C"), each=5),
              rbind(myd[[1]]$df, myd[[2]]$df, myd[[3]]$df))
mydf


## construct a lattice with multiple panels
my.lattice <-
  xyplot(y ~ x | group, data=mydf,
         layout=c(1,3), as.table=TRUE, col="black",
         scales=list(alternating=FALSE),
         ylab=list(rot=1))
my.lattice


## microplot provides latex.trellis, which is a method for Hmisc::latex

## simplest display
latex(my.lattice)

## now with comments and optional additional arguments
mycomments <-
  c("Interesting Comment",
    "Full \\LaTeX\\ with an equation $e^{-x^2}$",
    "\\begin{tabular}{l}$\\frac{dy}{dx}$ \\\\is interesting \\\\and
has multiple lines\\end{tabular}")

latex(my.lattice,
      title="Dataset",
      height.panel=1, width.panel=1.5, ## inches
      height.x.axis=.38, width.y.axis=.45,
      graph.header="xyplot(y ~ x | group)",
      dataobject=mycomments,
      colheads=c("Comments", "", "", "xyplot( y \\~{} x )"),
      caption="Very Interesting Caption",
      caption.loc="bottom",
      arraystretch=1.5)

## microplot produces MS Word tables as well as LaTeX tables.
## microplot works with  ‘Sweave’, ‘knitr’, ‘emacs’ ‘orgmode’, and ‘rmarkdown’

## Start with ?microplot-package
## and look at the demos and examples and vignette.

## Rich

On Thu, Aug 16, 2018 at 7:44 PM, MacQueen, Don via R-help
<[hidden email]> wrote:

> I would appreciate some suggestions of a good way to prepare a report using rmarkdown,
> in which I loop through subsets of a data set, creating a plot of each subset, and interspersing
> among the figures some text relevant to each figure.
>
> One way is to have an R script write the rmd file, then render it.
> It works, but it's cumbersome and difficult to get the rmd syntax correct.
> I would very much appreciate suggestions for a better way.
>
> Reproducible example below.
>
> Thanks
> -Don
>
>
> Example data (other data structures could be used), and an example using this approach.
>
> myd <- lapply( 1:3,
>               function(i) list(df=data.frame(x=1:5, y=rnorm(5)),
>                                comment=paste('Data', LETTERS[i]))
>               )
>
> Example interactive review (details would change depending on data structure)
> (I would typically insert pauses when working interactively)
>
> for (i in 1:3) {
>   cat(paste('Figure',i,'shows',myd[[i]]$comment),'\n')
>   with(myd[[i]]$df , plot(x,y))
>   mtext(myd[[i]]$comment)
>   mtext( paste(nrow(myd[[i]]$df),'points'), adj=1)
> }
>
> Note that along with the data I've saved some comments relevant to each subset.
> I've calculated them in the example data, but in general they could be completely
> arbitrary and come from anywhere.
>
> Now I'd like to get the same plots and comments into a report prepared using rmarkdown.
> Here's one way, having the loop create an rmd file, then rendering it.
>
> ### example script begins
> library(rmarkdown)
>
> myf <- 'myd.rmd'
> sink(myf)
> cat('---
> title: Example
> ---
>
> Here are some figures with a comment appearing before each.\n\n'
> )
> sink()
>
> for (i in 1:3) {
>   cat(paste('Figure',i,'comment:',myd[[i]]$comment),'\n', file=myf, append=TRUE)
>
>   cat("
> ```{r  echo=FALSE, fig.cap='",paste('fig',i),"caption.'}
>   with(myd[[",i,"]]$df , plot(x,y))
>   mtext(myd[[",i,"]]$comment)
>   mtext( paste(nrow(myd[[",i,"]]$df),'points'), adj=1)
> ```
> ", file=myf, append=TRUE)
>
> }
>
> cat('Done with report\n', file=myf, append=TRUE)
>
> render(myf)
>
> --
> Don MacQueen
> Lawrence Livermore National Laboratory
> 7000 East Ave., L-627
> Livermore, CA 94550
> 925-423-1062
> Lab cell 925-724-7509
>
>
>
> ______________________________________________
> [hidden email] mailing list -- To UNSUBSCRIBE and more, see
> https://stat.ethz.ch/mailman/listinfo/r-help
> PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
> and provide commented, minimal, self-contained, reproducible code.

______________________________________________
[hidden email] mailing list -- To UNSUBSCRIBE and more, see
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
and provide commented, minimal, self-contained, reproducible code.