Programmatically Creating Markdown Tables in R with Knitr

Programmatically creating Markdown tables in R with KnitR

Now knitr (since version 1.3) package include the kable function for a creation tables:

> library(knitr)
> kable(head(iris[,1:3]), format = "markdown")
| Sepal.Length| Sepal.Width| Petal.Length|
|-------------:|------------:|-------------:|
| 5,1| 3,5| 1,4|
| 4,9| 3,0| 1,4|
| 4,7| 3,2| 1,3|
| 4,6| 3,1| 1,5|
| 5,0| 3,6| 1,4|
| 5,4| 3,9| 1,7|

UPDATED: if you get raw markdown in a document try setup results = "asis" chunk option.

Programmatically create tab and plot in markdown

You can set results = 'asis' knitr option to generate the tabs in the map function using cat.

Getting Highcharter to work with asis was trickier :

  • Highchart needs to be called once before the asis chunck, probably to initialize properly, hence the first empty chart.
  • to print the chart in the asis chunck, the HTML output is sent in character format to cat

Try this:

---
title: "Test tabs"
output: html_document
---

`r knitr::opts_chunk$set(echo = FALSE, warning = FALSE, message = FALSE, cache = F)`

```{r}
library(highcharter)
library(tidyverse)
# This empty chart is necessary to initialize Highcharter in the tabs
highchart(height = 1)
```


```{r, results = 'asis'}
cat('## Tabs panel {.tabset} \n')
invisible(
iris %>%
dplyr::group_split(Species) %>%
purrr::imap(.,~{
# create tabset for each group
cat('### Tab',.y,' \n')
cat('\n')
p <- hchart(.x,"scatter", hcaes(x = Sepal.Length, y = Sepal.Width))
cat(as.character(htmltools::tagList(p)))
})
)
```

Sample Image

Note that while this solution works well, it goes beyond the original use for asis

Generate dynamic R-Markdown blocks with data.table objects

It works for me if I also generate the R blocks:

---
title: "R Notebook"
output:
html_document:
df_print: paged
---

```{r setup, echo=FALSE}
library(knitr)
library(data.table)
iris.dt <- data.table(iris)
iris.species <- as.character(unique(iris.dt$Species))
```

### View by Species automated {.tabset .tabset-fade .tabset-pills}
```{r run-numeric-md, include=FALSE}
out <- vector(mode = "character", length = length(iris.species))
for (i in iris.species) {
out[i] <- knit_expand(text = c("#### {{stringr::str_to_title(i)}}",
"```{r, echo = FALSE}",
"iris.dt[Species == '{{i}}']",
"```"))
}
```

`r paste(knit(text = out), collapse = '\n')`

knitr, R Markdown, and xtable: xtable tables within HTML table

I think your code will work if you put results=asis in the chunk options.

<table border = 1>
<tr>
<td>
```{r results='asis', echo=FALSE}
library(xtable)
data(tli)
print(xtable(tli[1:20, ]),type='html')
```
</td>
<td>
```{r results='asis', echo=FALSE}
library(xtable)
data(tli)
print(xtable(tli[1:20, ]),type='html',comment=FALSE)
```
</td>
</tr>
</table>

Why I do get another version of table?

You're not doing anything wrong. Try typing knitr::kable(head(mtcars[,1:4])) straight into the console and you will see the pipe format. Since you are evaluating it inside an r chunk, the pipe format gets rendered into HTML. The kable function is a shortcut; writing all those |: pipe characters manually would be cumbersome.

> knitr::kable(head(mtcars[,1:4]))


| | mpg| cyl| disp| hp|
|:-----------------|----:|---:|----:|---:|
|Mazda RX4 | 21.0| 6| 160| 110|
|Mazda RX4 Wag | 21.0| 6| 160| 110|
|Datsun 710 | 22.8| 4| 108| 93|
|Hornet 4 Drive | 21.4| 6| 258| 110|
|Hornet Sportabout | 18.7| 8| 360| 175|
|Valiant | 18.1| 6| 225| 105|

Referencing a table in R markdown with knitr

With format='pandoc' you need to enter the \label command in the caption.

With format='latex' the reference is automatically created as tab:chunk_label. For example,

---
output:
pdf_document
tables: true
---

```{r results='markup'}
tab <- head(iris)
knitr::kable(tab,
format='pandoc',
digits = 3,
caption = "Pandoc table\\label{tab:pandoc_table}"
)
```

```{r latex_table, results='markup'}
tab <- head(iris)
knitr::kable(tab,
format='latex',
digits = 3,
caption = "LaTeX table",
booktabs = TRUE
)
```

Table \ref{tab:pandoc_table} was done using Pandoc,
while Table \ref{tab:latex_table} used \LaTeX.

knitr printing list of data.frames with each table on new page

You can use purrr::imap to get the index in the .y variable:

``` r
library(kableExtra)
library(tidyverse)
library(purrr)

mt1 <-
matrix(
data = runif(n = 200, min = 101, max = 999)
,
nrow = 20
,
ncol = 10
,
byrow = TRUE
,
dimnames = list(LETTERS[1:20], paste0("V", 1:10))
)

df1 <- data.frame(Name = row.names(mt1), mt1)

dfs <-
unname(split.default(df1[,-1], as.integer(gl(
ncol(df1) - 1, 5, ncol(df1) - 1
))))

f <- function() {
for (i in 1:length(dfs)) {
print(
kable(
cbind(df1[1], dfs[i])
,
format = 'latex'
,
row.names = FALSE
) %>%
row_spec(
row = c(0),
bold = TRUE,
italic = TRUE,
align = "l"
)
)
if (i < length(dfs)) {
cat("\n\n\\newpage\n")
}
}
}

f_map <- function() {
invisible(dfs %>% purrr::imap(~ {
print(
kable(cbind(df1[1], .x)
, format = 'latex'
, row.names = FALSE) %>%
row_spec(
row = c(0),
bold = TRUE,
italic = TRUE,
align = "l"
)
#cat("\n\n\\newpage\n")
)
if (.y < length(dfs))
cat("\n\n\\newpage\n")
}))
}

identical(capture.output(f()), capture.output(f_map()))
#> [1] TRUE

microbenchmark::microbenchmark( f = {res <- capture.output(f())}, f_map = {res <- capture.output(f_map())})
#> Unit: milliseconds
#> expr min lq mean median uq max neval cld
#> f 7.908510 8.431997 9.662659 9.012099 10.10318 15.42358 100 a
#> f_map 7.983586 8.462561 9.797256 9.150356 10.71692 16.20676 100 a
```

<sup>Created on 2020-07-23 by the [reprex package](https://reprex.tidyverse.org) (v0.3.0)</sup>

As stated by @CL, this is not faster nor shorter than a simple loop.

How do I programmatically automate .rmd file to PDF using knitr?

To automate a knitr job you can use something like the command line below.

Rscript -e "library(knitr); knit2pdf('myRnw.Rnw')"

Put that in a .sh file and you can cron tab it all you want.

Explanation (aka the same again in English):

  • Rscript is the script-running version of R
  • Rscript -e "myexpression();" is the expression runner, it runs everything in the quotes. See Rscript --help for more detail.
  • library(knitr) -- well, you can't knit without knowing how, obviously neither can R
  • knit2pdf( '/path/to/file', ...) lookup the ? help on the function or search for more examples online.

Indentations in tables with lists in R markdown for HTML outputs

As I came to find out lists within tables in R markdown is not an intuitive business, even though the very similar answer how to write bullet lists for pdf with pandoc but the output is different and does not apply to my question. This person then asked
multi-level bullet lists problem is the output they are working on is for pdf with pandoc, and I'm outputting to HTML.

I found out with put that my breaks were with\r\n while others had \ \n and by removing the r this worked and playing with it I saw that depending on the space after the . that you can make indentations \ \n1.observation does not give an indentation while \ \n1. observation does. hope this helps someone as it took me a whole day to figure this out by myself! and if someone has any information how this works please let me know!



Related Topics



Leave a reply



Submit