rmarkdown powerpoint: two kable on one slide - r

In this example each kable is produced on one slide, even though the slide is large enough for 2.
---
title: "Untitled"
author: ""
date: "2/2/2022"
output: powerpoint_presentation
---
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = FALSE, message = FALSE, warning = FALSE, fig.height=5, fig.width=10)
```
## Slide with R Output
```{r}
knitr::kable(head(summary(cars),2))
```
```{r}
knitr::kable(head(summary(cars),2))
```
gives the output:
How do I make both kable on one slide one after the other.

You can use the gridExtra package https://cran.r-project.org/web/packages/gridExtra/vignettes/tableGrob.html
The documentation provides additional details about controlling formatting. I provided one example for illustration.
library(tidyverse)
library(gridExtra)
t1 <-
head(summary(cars),2) %>%
tableGrob(theme = ttheme_minimal(), rows = NULL)
tt3 <- ttheme_minimal(
core=list(bg_params = list(fill = blues9[1],
col=NA),
fg_params=list(fontface=3)),
colhead=list(fg_params=list(col="navyblue", fontface=4L)))
t2 <-
head(summary(cars),2) %>%
tableGrob(theme = tt3, rows = NULL)
grid.arrange(t1 , t2)

Related

Rotate table pdf output from Markdown

I want to rotate table output by 90 degrees on pdf. I am using markdown to generate a report and kable to display the tables in a loop. If possible, I would like to continue using kable since there are lot of other things which are dependent on it that I haven't included in this MWE.
This is a simple example using iris dataset. I tried using landscape function from this post Rotate a table from R markdown in pdf
---
output: pdf_document
header-includes:
\usepackage{lscape}
\usepackage{pdfpages}
---
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = FALSE)
```
Report page -
```{r results='asis'}
library(knitr)
library(kableExtra)
for (i in 1:3) {
print(landscape(kable_styling(
kable(iris[i:(i+5), ], format = "latex", align = "c", booktabs = TRUE,
longtable = TRUE, row.names = FALSE), latex_options = c("striped"), full_width = T)))
}
```
But this only rotates the page number keeping the table as it is.
I am actually looking for a solution which provides me the output in this way -
To clarify, all the pages with table data in it (3 for this example) should be rotated whereas rest of them should remain as it is. Also, I need longtable = TRUE in kable since in my actual example I am printing lot of rows.
Use package rotating
I added a simple example for you.
---
title: "test"
header-includes: \usepackage[figuresright]{rotating}
#or \usepackage[figuresleft]{rotating}
output:
pdf_document:
latex_engine: xelatex
---
```{r setup, include = FALSE}
library(flextable)
ft <- flextable(head(mtcars))
```
\begin{sidewaysfigure}
`r ft`
\end{sidewaysfigure}
```
Further you can modify it for your tasks ;)
I found another way using rotatebox.
---
output: pdf_document
header-includes:
\usepackage{lscape}
\usepackage{pdfpages}
\usepackage{graphicx}
\usepackage[figuresright]{rotating}
---
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = FALSE)
```
Report page -
```{r results='asis', warning=FALSE, message=FALSE}
library(knitr)
library(kableExtra)
for (i in 1:3) {
cat('\\rotatebox{90}{')
print(kable(iris[i:(i+5), ], format = "latex", align = "c", booktabs = TRUE,
row.names = FALSE))
cat('}')
cat("\n\\newpage\n")
}
```

Printing any number of dataframes stored in list as paged tables in rmarkdown

I often want to print out the dataframes contained in a list as paged tables in my rmarkdown documents. Calling each dataframe individually renders the desired ouptut if the right df_print option is selected. However, the point of having a list is that the number of dataframes varies depending on the parameters passed to the rmarkdown document; so that's no real solution.
Based on Vincent Guyader's answer to this question and on this example of rmarkdown::paged_table, I've tried to do the following without success.
Is there a way to achieve this at all? I'd be happy to use any package that supports pagination remotely resembling the df_print option.
---
title: "Printing paged tables from a list of dataframes in Rmarkdown"
output:
html_document:
df_print: paged
---
```{r}
library(DT)
library(rmarkdown)
library(purrr)
library(knitr)
df_list <- list("cars" = mtcars, "flowers" = iris)
knitr::opts_chunk$set(echo = FALSE, warning = FALSE, message = FALSE, results='asis')
```
### Desired output but impossible to generalise
```{r}
df_list[["cars"]]
```
```{r}
df_list[["flowers"]]
```
### datatable shows as blanks on the page
```{r}
map(df_list, ~DT::datatable(.x) %>%
htmltools::tagList() %>%
print())
```
### rmarkdown outputs dataframe contents as one very long string
```{r}
map(df_list, rmarkdown::paged_table)
```
The issue is that the JS dependencies needed to render the Datatable are not included in the HTML output. A workaround which I borrowed from here is to add a code chunk
```{r init-step, include=FALSE}
DT::datatable(mtcars)
```
outside of the loop or map statement which ensures that the JS dependencies are included. Also, I would recommend to switch to purrr::walk as using map has the effect that the tables are plotted twice.
---
title: "Printing paged tables from a list of dataframes in Rmarkdown"
output:
html_document:
df_print: paged
---
```{r}
library(DT)
library(rmarkdown)
library(purrr)
library(knitr)
df_list <- list("cars" = mtcars, "flowers" = iris)
knitr::opts_chunk$set(echo = FALSE, warning = FALSE, message = FALSE, results='asis')
```
### Desired output but impossible to generalise
```{r}
df_list[["cars"]]
```
```{r}
df_list[["flowers"]]
```
### datatable shows as blanks on the page
```{r init-step, include=FALSE}
DT::datatable(mtcars)
```
```{r}
walk(df_list, ~DT::datatable(.x) %>%
htmltools::tagList() %>%
print())
```
When using results='asis' argument, the renderer (here DT) has to be initialized once before being applied on a asis list.
This seems to be a general problem, see here with leaflet, and here with Highcharter.
The answer to this general question has been given here.
In this case:
---
title: "Printing paged tables from a list of dataframes in Rmarkdown"
output:
html_document:
df_print: paged
---
```{r,}
library(DT)
library(rmarkdown)
library(purrr)
library(knitr)
df_list <- list("cars" = mtcars, "flowers" = iris)
knitr::opts_chunk$set(echo = FALSE, warning = FALSE, message = FALSE, results='asis')
# initialize the renderer
data.frame() %>%
DT::datatable() %>%
knitr::knit_print() %>%
attr('knit_meta') %>%
knitr::knit_meta_add() %>%
invisible()
```
```{r , results='asis'}
#Remove already printed element and print the rest
df_list[[1]] <- NULL
map(df_list, ~DT::datatable(.x) %>%
htmltools::tagList() %>%
print())
```

[rmarkdown]How to deal with table in beamer_presentation

When I embed a table generated by using knitr::kable,
I want to adjust the width of the table in beamer_presentation's slide.
Like this picture, some columns don't show in slide when executing the following codes.
Could you tell me how to solve this problem without changing column's names?
---
title: "test"
author: "test"
date: "`r Sys.time()`"
output:
beamer_presentation:
latex_engine: xelatex
fontsize: 6pt
---
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = FALSE)
knitr::opts_chunk$set(warning = FALSE)
knitr::opts_chunk$set(include = FALSE)
library(tidyverse)
library(kableExtra)
library(knitr)
```
## Table
```{r test, results = "asis",include=TRUE}
test_tbl = tibble(
example_name1 = c("a", "b"),
example_name2 = c("aa", "bb"),
example_name3 = c("aaa", "bbb"),
example_name4 = c("aaaa", "bbbb"),
example_name5 = c("aaaaa", "bbbbb")
)
knitr::kable(test_tbl, format = "markdown")
```
The table is too large to fit on one slide. By adjusting the font size with kableExtra the size of the table can be changed. To do this, set the argument format = "latex" in kable() and then pipe kable_styling().
knitr::kable(test_tbl, format = "latex") %>%
kableExtra::kable_styling(font_size = 7)
It is useful to include LaTeX packages like booktabs to format tables nicely with kable or kableExtra. This is not as flexible as working with LaTeX directly but often leads to quite good results.
First of all, include booktabs in the YAML header.
---
title: "test"
author: "test"
date: "`r Sys.time()`"
header-includes:
- \usepackage{booktabs}
output: beamer_presentation
---
Then set booktabs = TRUE in kable().
knitr::kable(test_tbl, format = "latex", booktabs = T) %>%
kableExtra::kable_styling(font_size = 7)

how to use a for loop in rmarkdown?

Consider this simple example:
---
title: "Untitled"
output: ioslides_presentation
---
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = FALSE)
```
## Slide with R Output
```{r t, warning=FALSE, message=FALSE}
library(knitr)
library(kableExtra)
library(dplyr)
for(threshold in c(20, 25)) {
cars %>%
filter(dist < threshold) %>%
kable('html') %>%
kable_styling(bootstrap_options = "striped")
}
```
Here I simply want to print each output of the for loop into a different slide. In this example, there are two calls to kablethat should go on two different slides.
The code above does not work. Am I even using the right packages for that? Any ideas?
Thanks!
You can use the asis option:
---
title: "Untitled"
output: ioslides_presentation
---
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = FALSE)
library(knitr)
library(kableExtra)
library(dplyr)
# needed so r will include javascript/css dependencies needed for striped tables:
kable(cars, "html") %>% kable_styling(bootstrap_options = "striped")
```
```{r, results = "asis"}
for (threshold in c(20, 25)) {
cat("\n\n##\n\n")
x <- cars %>%
filter(dist < threshold) %>%
kable('html') %>%
kable_styling(bootstrap_options = "striped")
cat(x)
}
```
To get rid of that bogus table, you can try to put options(kableExtra.html.bsTable = T) in your setup section.
Here's the start of a solution. You can print strings with markdown, either by making the strings yourself or using pander's pandoc.* functions. If you set results="asis" for that chunk, it will get compiled the same as any other markdown. I used cat to make the ## headings, but commented out two pander functions that you could try also to make headers or horizontal rules to split slides.
There's more detail on the pander functions here, plus other SO questions such as this one.
---
title: "Untitled"
output: ioslides_presentation
---
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = FALSE)
library(knitr)
library(kableExtra)
library(dplyr)
```
```{r, results='asis'}
for(threshold in c(20, 25)) {
# pander::pandoc.header(sprintf("Threshold = %s", threshold))
# pander::pandoc.horizontal.rule()
cat(paste("\n##", "Threshold =", threshold), "\n")
tbl <- cars %>%
filter(dist < threshold) %>%
kable(format = "html") %>%
kable_styling(bootstrap_options = "striped")
print(tbl)
}
```
One issue is that when I knit this, I'm not getting the striped table that you'd expect. If I add a slide before this chunk and put a table in it with these kableExtra settings, I do get stripes, but the first table is also pretty ugly...I'm not sure if that's a bug or conflicting CSS somewhere or what.

Align multiple tables side by side

The following code produces 2 tables on top of each other. How would I set it to have them aligned side by side, e.g. 3 to a row?
---
title: "sample"
output: pdf_document
---
```{r global_options, R.options=knitr::opts_chunk$set(warning=FALSE, message=FALSE)}
```
```{r sample, echo=FALSE, results='asis'}
library(knitr)
t1 <- head(mtcars)[1:3]
t2 <- head(mtcars)[4:6]
print(kable(t1))
print(kable(t2))
```
Output looks like this:
Just put two data frames in a list, e.g.
t1 <- head(mtcars)[1:3]
t2 <- head(mtcars)[4:6]
knitr::kable(list(t1, t2))
Note this requires knitr >= 1.13.
I used this Align two data.frames next to each other with knitr? which shows how to do it in html and this https://tex.stackexchange.com/questions/2832/how-can-i-have-two-tables-side-by-side to align 2 Latex tables next to each other. It seems that you cannot freely adjust the lines of the table as you can do it with xtable (does anybody know more about this?). With format = Latex you get a horizontal line after each row. But the documentation shows two examples for other formats. One using the longtable package (additional argument: longtable = TRUE) and the other using the booktabs package (booktabs = TRUE).
---
title: "sample"
output: pdf_document
header-includes:
- \usepackage{booktabs}
---
```{r global_options, R.options=knitr::opts_chunk$set(warning=FALSE, message=FALSE)}
```
```{r sample, echo=FALSE, results='asis'}
library(knitr)
library(xtable)
t1 <- kable(head(mtcars)[1:3], format = "latex", booktabs = TRUE)
t2 <- kable(head(mtcars)[4:6], format = "latex", booktabs = TRUE)
cat(c("\\begin{table}[!htb]
\\begin{minipage}{.5\\linewidth}
\\caption{}
\\centering",
t1,
"\\end{minipage}%
\\begin{minipage}{.5\\linewidth}
\\centering
\\caption{}",
t2,
"\\end{minipage}
\\end{table}"
))
```
here a solution for html documents
(As this question was asked very broadly and not specifically referring to LaTeX).
Requires knitr and kableExtra
---
title: "Side by side"
output: html_document
---
```{r sample, echo=FALSE}
library(knitr)
library(kableExtra)
t1 <- head(mtcars)[1:3]
t2 <- head(mtcars)[4:6]
```
## as list
```{r}
kable(list(t1, t2))
```
## with float
```{r, echo = FALSE}
kable(t1) %>%
kable_styling(full_width = FALSE, position = "float_left")
kable(t2) %>%
kable_styling(full_width = FALSE, position = "left")
```
It is intentional that table t2 gets position = "left". If you allow it to float, this will not block the rest of the paragraph and mess up the following lines in your document.
result:
In Quarto, you can use layout-ncol. This works both for HTML and PDF outputs.
---
title: "sidebyside"
format: pdf
editor: visual
---
```{r}
#| layout-ncol: 2
#| tbl-cap: "Tables"
#| tbl-subcap: ["A table", "Another table"]
library(knitr)
# table on the left
kable(head(mtcars))
# table on the right
kable(head(cars))
```

Resources