How to create a markdown document for each row of data in R

I would like to create either one document with markup with subdocuments from each row of the data frame, or create the number of frames for documents with delimiters. The discounted document is a template. Link.

I think it should work to create a for loop, but when I try to do this, by(dataFrame, 1:nrow(dataFrame), function(row) knit(file = "/Users/path/template.Rmd")) I get an error message that the login ended unexpectedly.

 Quitting from lines 23-26 (Preview-e0d353674d36.Rmd) Error in knit(file = "/Users/path/template.Rmd") : unused argument (file = "/Users/path/template.Rmd") Calls: <Anonymous> ... eval -> eval -> tapply -> lapply -> FUN -> FUN -> knit Execution halted 

I tried to use the same amazing approach that @Yihui decided to programmatically reference text with the knitr-expand extension presented here: R knitr: is it possible to programmatically modify block labels?

From this solution, we have two .Rmd files, My report and Template My report is as follows:

 # My report ```{r} data(mtcars) cyl.levels <- unique(mtcars$cyl) ``` ## Generate report for each level of cylinder variable ```{r, include=FALSE} src <- lapply(cyl.levels, function(ncyl) knit_expand(file = "template.Rmd")) ``` `r knit(text = unlist(src))` 

The template looks like this:

 ```{r, results='asis'} cat("### {{ncyl}} cylinders") ``` ```{r mpg-histogram-{{ncyl}}cyl} hist(mtcars$mpg[mtcars$cyl == {{ncyl}}], main = paste({{ncyl}}, "cylinders")) ``` ```{r weight-histogam-{{ncyl}}cyl} hist(mtcars$wt[mtcars$cyl == {{ncyl}}], main = paste({{ncyl}}, "cylinders")) ``` 

This solution creates a single markdown document with a subdocument (at heading level 2) for each cylinder level. However, I am trying to create a report that retrieves .csv, and then creates and modifies the data frame and creates content for each row of the other frame.

I think I'm stuck on how to use the value in {{ncyl}} to programmatically access database rows. I would like to be able to use the {{ncyl}} levels to go and do things with the corresponding rows in the mtscars dataframe (assuming that for this example there were only rows == levels {{ncyl}}).

While data(mtcars) has more rows than cylyinder levels, R stores the value {{ncyl}} as an integer. So you can call mtcars$gear[[{{ncyl}}]] and get the gear value for the string {{ncyl}}.

Why then, when we add this to our .Rmd template, does it fail?

Forgive me, this will not fail, it will give us gear <- mtcars$gear[[{{ncyl}}]] , but we will not be able to create a piece of equipment, for example, ```{r this-gear-{{gear}}} .

It works

 ```{r} gear <- mtcars$gear[[{{ncyl}}]] gear ``` ```{r, results='asis'} cat("### {{ncyl}} cylinders") ``` ```{r mpg-histogram-{{ncyl}}cyl} hist(mtcars$mpg[mtcars$cyl == {{ncyl}}], main = paste({{ncyl}}, "cylinders")) ``` ```{r weight-histogam-{{ncyl}}cyl} hist(mtcars$wt[mtcars$cyl == {{ncyl}}], main = paste({{ncyl}}, "cylinders")) ``` 

This does not work

 ```{r} gear <- mtcars$gear[[{{ncyl}}]] gear ``` ```{r, results='asis'} cat("### {{ncyl}} cylinders") ``` ```{r mpg-histogram-{{ncyl}}cyl} hist(mtcars$mpg[mtcars$cyl == {{ncyl}}], main = paste({{ncyl}}, "cylinders")) ``` ```{r weight-histogam-{{ncyl}}cyl} hist(mtcars$wt[mtcars$cyl == {{ncyl}}], main = paste({{ncyl}}, "cylinders")) ``` ```{r {{gear}}} gear ``` 

Error provision

 Quitting from lines 10-12 (Preview-e0d32d687661.Rmd) Error in eval(expr, envir, enclos) : object 'gear' not found Calls: <Anonymous> ... knit_expand -> inline_exec -> withVisible -> eval -> eval Execution halted 

I think I'm getting closer to the main problem "How to create a markdown document for each line of the frame?" wrong with knitting function.

Can someone help me understand: 1. How to solve the main problem 2. Why {{gear}} does not work in the .Rmd template?

So, I still do not understand (2), but I think that @daroczig drew me close to understanding one way to solve the main problem. I do not think this is too unique for the problem, and I assume that there is a way to solve it without brew or pander or rapport . In any case, I took the brew approach and did something with several rows of data. This causes an error. Notice that I am not doing anything reasonable with this code, just limiting mtcars to 3 lines, so I don't get too much output, and then I create another lame dataframe in a for loop.

 # My report <% mtcars1 <- mtcars[1:3,] mtcars1$type <- c('red','blue','green') t.levels <- unique(mtcars1$type) for (ty in t.levels) { p <- subset(mtcars1,type == ty) x <- rep(p, 4) short <- paste0(p$gear, p$mpg) %> ### <%= short %> blah <%= hist(x$mpg, main = paste(short, "blah")) %> <% } %> 

This is just a small chronic modification to the solution suggested by @daroczig below. It works if we call it demo.brew and call it Pandoc.brew('demo.brew', output = tempfile(), convert = 'html') . Let's make one stupid example.

(3) Is there an example of how to do this without brew? I am curious.

Reply to (3) Yes. This works with a for loop that calls a variable instead of a num string

 varlist <- unique(df$variable) for (var in varlist) { try(knit2html(input= '/Users/path/template.Rmd', output=paste0('/Users/path/template',var,'.html'))) 

Works where a loop of 1: nrow () does not work.

+5
source share
1 answer

Alternative solution with pander - based on my comment:

 # My report <% cyl.levels <- unique(mtcars$cyl) for (ncyl in cyl.levels) { %> ### <%= ncyl %> cylinders <%= hist(mtcars$mpg[mtcars$cyl == ncyl], main = paste(ncyl, "cylinders")) hist(mtcars$wt[mtcars$cyl == ncyl], main = paste(ncyl, "cylinders")) %> <% } %> 

In brew, this file (named demo.brew ) run:

 Pandoc.brew('demo.brew') 

Or get, for example, an MS Word document:

 Pandoc.brew('demo.brew', output = tempfile(), convert = 'docx') 

Update . I just realized that you need separate documents for the categories. For this, I would suggest another package, rapport , an attempt that focuses on precisely statistical report templates. Quick example:

 <!--head meta: title: Demo for @Jessi author: daroczig description: This is a demo packages: ~ inputs: - name: ncyl class: integer standalone: TRUE required: TRUE head--> ### <%= ncyl %> cylinders <%= hist(mtcars$mpg[mtcars$cyl == ncyl], main = paste(ncyl, "cylinders")) hist(mtcars$wt[mtcars$cyl == ncyl], main = paste(ncyl, "cylinders")) %> 

So this above document ( demo.rapport ) is a rapport template that has a YAML header for metadata and inputs (which acts as parameters / arguments in R functions), then the body can include markdown and R code in brew syntax with pander . Now you can easily call this report template with a simple call, for example. for 4 cylinders:

 > rapport('demo.rapport', ncyl = 4) ### _4_ cylinders ![](plots/rapport--home-daroczig-projects-demo.rapport-6-1.png) ![](plots/rapport--home-daroczig-projects-demo.rapport-6-2.png) 

And to create an MS Word file for all cylinders, try the following:

 for (ncyl in (2:4)*2) { rapport.docx('/home/daroczig/projects/demo.rapport', ncyl = ncyl) } 
+2
source

Source: https://habr.com/ru/post/1200759/


All Articles