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 theasis
chunck, probably to initialize properly, hence the first empty chart.- to print the chart in the
asis
chunck, the HTML output is sent incharacter
format tocat
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)))
})
)
```
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
How to Define More Line Types for Graphs in R (Custom Linetype)
Controlling Order of Facet_Grid/Facet_Wrap in Ggplot2
Bigrams Instead of Single Words in Termdocument Matrix Using R and Rweka
Plots Generated by 'Plot' and 'Ggplot' Side-By-Side
Returning Above and Below Rows of Specific Rows in R Dataframe
Divide Row Value by Aggregated Sum in R Data.Frame
Complete Column with Group_By and Complete
How to Have a Multi-Line Comments in R
Suggestions for Speeding Up Random Forests
How to Delete Groups Containing Less Than 3 Rows of Data in R
Error in Installation a R Package
Replace All Values in a Matrix <0.1 with 0
Use Ggpairs to Create This Plot
Add a Box for the Na Values to the Ggplot Legend for a Continuous Map
Rounding Numbers in R to Specified Number of Digits
Dt: Dynamically Change Column Values Based on Selectinput from Another Column in R Shiny App