Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does datatable not print when looping in rmarkdown?

I am working on creating a dynamic rmarkdown document. The end result should create a tab for each 'classification' in the data. Each tab should have a datatable, from the DT package, with the data printed to it. Below is the code I have been using:

---
output: html_document
---

# Setup{.tabset}
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = FALSE)
library(knitr)
library(DT)
```

```{r data.setup}
set.seed = 1242
rows = 64
data.1 = runif(rows, 25, 75)
data.2 = runif(rows, .01, 1)
data.3 = runif(rows, 1, 10)
classification = c("A", "B", "C", "D")
df = data.frame(cbind(data.1 = data.1, data.2 = data.2, data.3 = data.3, classification = classification))
df$data.1 = as.numeric(df$data.1)
df$data.2 = as.numeric(df$data.2)
df$data.3 = as.numeric(df$data.3)
```

```{r results= 'asis'}
for(j in levels(df$classification)){
        df.j = df[df$classification == j, ]
        cat(paste("\n\n## Classification: ", j, "##\n"))
        w = datatable(df.j)
        #datatable(df.j)
        print(w)
}
```

Notice I have commented out straight calls to the datatable function, those were not printing to rmarkdown. The results of the call as written generate an html document with the correct tabs, but no datatables in them. Additionally, the datatables actually display in my RStudio session with the correct subsetting. As a test, I tried achieving the goal using the kable function from knitr, and the tables were printed in their appropriate tabs, unfortunately, kable does not have all the functionality required.

like image 712
Richard Lusch Avatar asked Sep 27 '16 19:09

Richard Lusch


People also ask

How do you show results in RMarkdown?

To produce a complete report containing all text, code, and results, click “Knit” or press Cmd/Ctrl + Shift + K. You can also do this programmatically with rmarkdown::render("1-example. Rmd") .

Why is my RMarkdown not knitting?

If a chunk works in R but not when you knit, it is almost always because you've changed a variable in your global working environment not using code in a chunk. Try restarting your R session and running each chunk sequentially to make sure all your variable values are up to date.

What does ## do in R markdown?

Text: Also on this page, one can see text sections, for example, one section starts with “## R Markdown” this section will render as text when the PDF of this file is produced and all of the formattings that the user will learn generally applies to this section.

What kind s of output files can a RMarkdown document generate?

Rendering output R Markdown generates a new file that contains selected text, code, and results from the . Rmd file. The new file can be a finished web page, PDF, MS Word document, slide show, notebook, handout, book, dashboard, package vignette or other format.


2 Answers

This is not a complete answer as some of this is still puzzling me, but at least this is good enough to get you going while I try to understand some more.

---
output: html_document
---

# Setup{.tabset}
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = FALSE)
library(knitr)
library(DT)
```

```{r data.setup}
set.seed <- 1242
rows <- 64
data.1 <- runif(rows, 25, 75)
data.2 <- runif(rows, .01, 1)
data.3 <- runif(rows, 1, 10)
classification <- c("A", "B", "C", "D")
df <- data.frame(cbind(data.1 = data.1, data.2 = data.2, data.3 = data.3, classification = classification))
df$data.1 <- as.numeric(df$data.1)
df$data.2 <- as.numeric(df$data.2)
df$data.3 <- as.numeric(df$data.3)
```

```{r include = FALSE}
# Why, oh why do I need this chunk?
datatable(df)
```

```{r results = 'asis'}
for(j in unique(df$classification)){ # You were using level() here, so your for-loop never got off the ground
        df.j <- df[df$classification == j, ]
        cat(paste("\n\n## Classification: ", j, "##\n"))
        print( htmltools::tagList(datatable(df.j)) )
}

The third chunk is required for this to work, I'm not yet sure why.

like image 147
Chrisss Avatar answered Sep 19 '22 00:09

Chrisss


Reaching here by googling the same question. This has worked for me: https://gist.github.com/ReportMort/9ccb544a337fd1778179.

Basically, generate a list of rendered tibbles and manually call knit.

Here is a working Rmd based on your example, using the technique found in the above link:

---
output: html_document
---

# Setup{.tabset}
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = FALSE)
library(knitr)
library(DT)
```

```{r data.setup}
set.seed <- 1242
rows <- 64
data.1 <- runif(rows, 25, 75)
data.2 <- runif(rows, .01, 1)
data.3 <- runif(rows, 1, 10)
classification <- c("A", "B", "C", "D")
df <- data.frame(cbind(data.1 = data.1, data.2 = data.2, data.3 = data.3, classification = classification))
df$data.1 <- as.numeric(df$data.1)
df$data.2 <- as.numeric(df$data.2)
df$data.3 <- as.numeric(df$data.3)
```

```{r include = FALSE}
# prepare a list of 4 sub-dataframes, each corresponding to one classification
df_list <- split(df, df$classification)
```

```{r create-markdown-chunks-dynamically, include=FALSE}

out = NULL
for (c in names(df_list)) {
  knit_expanded <- paste0("\n\n## Classification: ", c, "##\n\n```{r results='asis', echo=FALSE}\n\ndatatable(df_list[['", c, "']])\n\n```")
  out = c(out, knit_expanded)
}

```

<!--- knit those table chunk statements --> 
`r paste(knit(text = out), collapse = '\n')`
like image 42
Yue Jiang Avatar answered Sep 17 '22 00:09

Yue Jiang