R kableExtra latex: Add linebreaks to rotated header row - r

I'm trying to produce table to a Latex-pdf document. I'm using kableExtra and knitr in R.
I have a table that has long column names. When I rotate the header row by 90 degrees linebreaks won't work. Does anyone have an idea how I could achieve both rotated row and linebreaks?
My example is the same as in Hao's Best Practice for newline in Latex table, but I added piped row_spec to the end of the code.
\documentclass[10pt,a4paper]{article}
\usepackage[table]{xcolor}
\begin{document}
\begin{table}
<<global_options, echo=FALSE>>=
library(kableExtra)
library("dplyr")
dt_lb <- data.frame(
Item = c("Hello\nWorld", "This\nis a cat"),
Value = c(10, 100)
)
dt_lb %>%
mutate_all(linebreak) %>%
kable("latex", booktabs = T, escape = F,
col.names = linebreak(c("Item\n(Name)", "Value\n(Number)"))) %>%
row_spec(0, angle = 90, align='l', monospace=T)
#
\end{table}
\end{document}
What I get is this, but the [l] tags hint that there's something else wrong with the tags as well:
On StackExchange TEX I found a question about rotation and linebreaks, this is what I'm trying achieve: https://tex.stackexchange.com/questions/14730/big-table-with-rotated-column-labels-using-booktabs

You could use tableHTML:
library(tableHTML)
Replace the new line character "\n" with the HTML tag <br>:
headers <- c("Item\n(Name)", "Value\n(Number)") %>%
stringr::str_replace_all(pattern = "\\n", replacement = "<br>")
Create a tableHTML object and rotate the headers using add_css_header():
dt_lb %>%
tableHTML(rownames = FALSE,
headers = headers,
escape = FALSE,
widths = c(100, 100),
theme = 'scientific') %>%
add_css_header(css = list(c('transform', 'height', 'text-align'),
c('rotate(-45deg)', '70px', 'center')),
headers = 1:2)
The result looks like this:
Note: you can add more css or default themes. Check out the vignettes for more details:
If you want to create a pdf document, you could use RMarkdown:
---
title: "tableHTML2pdf"
output: html_document
---
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = FALSE)
```
\
```{r}
library(tableHTML)
dt_lb <- data.frame(
Item = c("Hello\nWorld", "This\nis a cat"),
Value = c(10, 100)
)
headers <- c("Item\n(Name)", "Value\n(Number)") %>%
stringr::str_replace_all(pattern = "\\n", replacement = "<br>")
dt_lb %>%
tableHTML(rownames = FALSE,
headers = headers,
escape = FALSE,
widths = c(100, 100),
theme = 'scientific') %>%
add_css_header(css = list(c('transform', 'height', 'text-align'),
c('rotate(-45deg)', '70px', 'center')),
headers = 1:2)
```
\
It will then create an HTML file. This file can then be converted to PDF using wkhtmltopdf.

I think you probably rendered your rmarkdown document into HTML... In the rmarkdown yaml header, does it say html_document right now? If so, you can try to change it to pdf_document.....
I rendered a pdf_document with exactly the same code and I think I got what you were looking for...
---
title: "Table Sample"
output: pdf_document
---
``` {r, include = FALSE}
library(tidyverse)
library(kableExtra)
```
```{r}
dt_lb <- data.frame(
Item = c("Hello\nWorld", "This\nis a cat"),
Value = c(10, 100)
)
dt_lb %>%
mutate_all(linebreak) %>%
kable("latex", booktabs = T, escape = F,
col.names = linebreak(c("Item\n(Name)", "Value\n(Number)"), align = "c")) %>%
row_spec(0, angle = 90)
```

Latex package makecell was missing.
Hao pointed out that Page 3 of this manual lists some of the necessary Latex packages: haozhu233.github.io/kableExtra/awesome_table_in_pdf.pdf

Related

Is there a way to automatically position and fit a flextable object on a PowerPoint slide using RMarkdown?

The problem
When I generate a flextable object to be printed to a PowerPoint slide using RMarkdown, RMarkdown just sort of...throws the table on the slide.
```{r example}
tibble(
COL_1 = seq(1, 25),
COL_2 = seq(1, 25),
COL_3 = seq(1, 25),
COL_4 = seq(1, 25),
COL_5 = seq(1, 25)
) |>
qflextable() |>
add_footer_row(values = "This is some example text just to highlight what gets lost in normal formatting.", colwidths = 5)
```
With the above code, I end up with something like this:
What I want
Ideally, I'd like my table to be centered on the slide and formatted to fit, as in the below:
Does anyone have any suggestions on how I can get the desired result without manually editing the slide in PowerPoint?
Note that this question was previously posed but did not receive a workable answer.
You can achieve that by using "officedown". But it requires some calculation. First know the slide dimensions (with office::slide_size()), then the flextable dimensions (with flextable_dim()) and finally compute the left and top positions that will be used by PowerPoint.
Flextable can be positioned in the slide with knitr chunk parameters ft.left and ft.top.
The following is illustrating the quick explanation.
---
output:
officedown::rpptx_document:
reference_doc: template_demo.pptx
---
```{r include=FALSE}
knitr::opts_chunk$set(echo = FALSE)
library(officedown)
library(officer)
library(flextable)
library(magrittr)
sl_size <- read_pptx("template_demo.pptx") %>%
add_slide(layout = "Title and Content", master = "Office Theme") %>%
slide_size()
s_w <- sl_size$width
s_h <- sl_size$height
ft <- flextable(head(iris)) %>%
fontsize(size = 18, part = "all") %>%
theme_vader() %>%
autofit()
ft_dim <- flextable_dim(ft)
left <- (s_w/2) - (ft_dim$widths/2)
top <- (s_h/2) - (ft_dim$heights/2)
```
```{r ft.left=left, ft.top=top}
ft
```

R Aligning table content to decimal points in kable

I've created a table in RMarkdwon (PDF) with the knitr and kableExtra packages.
I can choose in the kable-function between left,center or right- alignments.
But I want that the content of the table cells are aligned to the decimal points.
In this case it is difficult since there are asterisks behind the numbers indicating the significance.
Here is a reproduceable example:
library(tidyverse)
library(knitr)
library(kableExtra)
tribble(
~Variable_1,~Variable_2,
"13.5","4.4**",
"12.7***","1.2*",
"0.4","0.3***",
"2.3**","11.5**"
)%>%
kable(format = "latex", booktabs=T, escape = T)%>%
kable_styling(position = "center", latex_options = "hold_position")
Which produces this table:
Can someone give me an easy solution directly in R?
If this should not be possible, how would an edit in the latex code look like?
Many thanks in advance!
Here is the table provided by bttomio:
One solution could be intersing the variable names in {} recommended by https://haozhu233.github.io/kableExtra/awesome_table_in_pdf.pdf page 28.
The code then looks like this:
tribble(
~Variable_1,~Variable_2,
"13.5","4.4**",
"12.7***","1.2*",
"0.4","0.3***",
"2.3**","11.5**"
)%>%
rename_all( ~ str_c("{ ",.," }"))%>%
kable(format = "latex", booktabs=T, escape = T)%>%
kable_styling(position = "center", latex_options = "hold_position")
And the table corresponds to the desired output:
But the problem is the full-width-option in the kable_styling-function. If I set this option to TRUE the linebreak of large column names disappears.
Here is a first try:
---
output: pdf_document
header-includes:
- '\usepackage{siunitx}'
- '\newcolumntype{d}{S[table-format=3.2]}'
---
```{r}
library(tidyverse)
library(knitr)
library(kableExtra)
tribble(
~Variable_1,~Variable_2,
"13.5","4.4**",
"12.7***","1.2*",
"0.4","0.3***",
"2.3**","11.5**"
)%>%
kable(format = "latex", booktabs=T, escape = T, align = "d")%>%
kable_styling(position = "center", latex_options = "hold_position")
```

column_spec function in kableExtra in R doesn't work

I want co change column width in pdf with kable ( , 'latex') but the fucntion doesn't work. Anybody know why? here is my code:
table = knitr::kable(jeden, "latex" , row.names = F , align = "llrrrrrrrrrr" , escape = F, booktabs = F, caption = '1. Sprzedaz uslug i towarow razem')
kableExtra::column_spec(table, 1, width = "1cm", bold = TRUE, italic = TRUE)
It's not a bug but rather a relatively strange setting for align in knitr::kable(). In xtable you can put align in a string but for kable, you will have to provide a vector. In your case, if you put things like align = c(rep("l", 2), rep("r"), 2), you should be fine.
It seems that align breaks your column_spec, but only for LaTeX/PDF output.
Here are two minimal & reproducible examples.
PDF output
---
title: "Untitled"
output:
pdf_document: default
---
```{r}
library(knitr)
library(kableExtra)
x <- kable(head(mtcars[, 1:4]), "latex", row.names = F, align = "llrr")
column_spec(x, 1:2, width = "4cm", bold = TRUE, italic = TRUE)
```
If you remove align from the PDF RMarkdown document, column_spec works as expected.
HTML output
---
title: "Untitled"
output:
html_document: default
---
```{r}
library(knitr)
library(kableExtra)
x <- kable(head(mtcars[, 1:4]), "html", row.names = F, align = "llrr")
column_spec(x, 1:2, width = "4cm", bold = TRUE, italic = TRUE)
```
This seems like a bug to me, and I would suggest opening an issue on the kableExtra GitHub site. If you do, you should reference this post, and include a minimal & reproducible example (similar to what I did).

Pixiedust table in loop in r markdown not rendering

Relevant to the problem, I have a dataset with factors of states ("Massachusetts", "California", etc) and 2 fields of values. I would like to create a graph for each state with a table below it showing the associated fields and the difference between those fields.
I found that using a loop seems to require a results = 'asis' option and a cat(" \n") at the end of the loop to print the images. That works OK. However, the only way I can seem to get a table is if I use xtable or kable. I would like to use pixiedust to color and otherwise beautify the table.
Here is a minimal example:
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
library(pixiedust)
library(ggplot2)
library(knitr)
library(xtable)
df <- data.frame(state = c("MA", "CA"), last_year = c(105, 90), this_year = c(110, 85))
```
# Here is the loop
```{r loops, results = 'asis', echo = FALSE}
for (i in 1:nrow(df)){
state_dat <- df[i,]
p1 <- ggplot(state_dat, aes(last_year, this_year)) +
geom_point()
print(p1)
cat(" \n")
tab <- data.frame(last_year = state_dat$last_year, this_year = state_dat$this_year, yoy_percent = 100*(state_dat$this_year - state_dat$last_year)/state_dat$last_year)
dust(tab) %>%
sprinkle(rows = 1, bg = "orchid")
cat(" \n")
print(kable(tab, row.names = FALSE, align = "c"))
cat(" \n")
print(xtable(tab, auto = TRUE),type = "html", comment = FALSE, include.rownames = F)
cat(" \n")
}
```
I also tried assigning the result of the dust commands to an object and printing that:
pixie <- dust(tab) %>%
sprinkle(rows = 1, bg = "orchid")
print(pixie)
cat(" \n")
to no avail.
Can pixiedust tables be produced as html in a chunk with option asis? Is there another workaround to produce a table and a graph in a loop?
Yes, this can be done. To get there, you have to turn off the asis printing in the print.dust method. This can be done with:
dust(tab) %>%
sprinkle(rows = 1, bg = "orchid") %>%
print(asis = FALSE) %>%
cat()
In time, I hope to come up with a better solution.

Suppress alt text for GIFs in rmarkdown HTML output

I'm generating GIFs using the gganimate package within an RMarkdown file. When using output = github_document in the front matter, the GIF appears as expected in the output (github-document-output). However, when using output = html_document, the GIF generates with alt text, which defaults to the chunk name (html-document-output).
Is there a way to suppress this automatic caption? I've tried setting my own caption using the fig.cap chunk option, but that was unsuccessful.
RMarkdown code
---
output:
html_document: default
github_document: default
---
```{r}
knitr::opts_chunk$set(
collapse = TRUE,
comment = "#>",
fig.path = "output/test-fig-",
cache.path = "output/test-cache-"
)
```
```{r cache = FALSE}
library(knitr)
library(animation)
ani.options(autobrowse = FALSE, interval = 1)
opts_knit$set(animation.fun = function(x, options, format = "gif") {
x = c(knitr:::sans_ext(x), knitr:::file_ext(x))
fig.num = options$fig.num
format = sub("^[.]", "", format)
fig.fname = paste0(sub(paste0(fig.num, "$"), "*", x[1]),
".", x[2])
mov.fname = paste0(sub(paste0(fig.num, "$"), "", x[1]), ".",
format)
# order correctly
figs <- Sys.glob(fig.fname)
figs <- figs[order(as.numeric(stringr::str_match(figs, paste0("(\\d+)\\.", x[2]))[, 2]))]
animation::im.convert(figs, output = mov.fname)
sprintf("![%s](%s)", options$label, paste0(opts_knit$get("base.url"), mov.fname))
})
opts_chunk$set(cache = TRUE, message = FALSE, warning = FALSE, fig.show = "animate")
```
```{r pkgs, cache = FALSE}
library(gapminder)
library(ggplot2)
theme_set(theme_bw())
```
```{r setup}
p <- ggplot(gapminder, aes(gdpPercap, lifeExp, size = pop, color = continent, frame = year)) +
geom_point() +
scale_x_log10()
```
```{r dependson = "setup"}
library(gganimate)
gg_animate(p)
```
The problem here is that you include the resulting animation with markdown syntax. This introduces some iiritations I guess.
Taking a look at hook_plot_html we can simulate the default output for standard plots:
sprintf(paste0('<div class="figure %s">',
'<img src="%s">',
'<p class="caption">%s</p>',
'</div>'), options$fig.align, mov.fname, options$fig.cap)

Resources