Wrapping footnote to second line to fit table in kable (LaTeX .Rmd) - r

I'm wondering if there is a way I can force a footnote to fit the width of a table (and wrap to a second line) using kable in R (I'm knitting .Rmd to PDF so the format is latex). I've used both add_footnote() and footnote(). The add_footnote function will actually wrap a footnote to a second line if it extends beyond the width of the table, but it also forces the use of superscripts (which for this sake is something I can't have in my table). footnote gives me the option to remove the superscript but I'm not sure how to get it to match the formatting of add_footnote and wrap footnotes that are wider than the table to a second line. Another solution would be to remove the superscripts from add_footnote
\captionsetup[table]{labelformat=empty}
```{r packs}
library(pacman)
p_load(tidyverse,knitr,kableExtra,janitor)
mydf <-data_frame(x=1:4,y=2:5,z=3:6)
fn1='This the footnote 1'
fn2='This is footnote 2 and is much longer'
mydf %>%
kable(format='latex',booktabs=T,
col.names=c('X','Y','Z'),
caption=c('This method stretches', 'my table out in an ugly way')) %>%
kable_styling(latex_options = c('hold_position')) %>%
footnote(general=c(fn1, fn2),general_title="")
mydf %>%
kable(format='latex',booktabs=T,
col.names=c('X','Y','Z'),
caption=c('This method ruins my title', 'and left justifies my table')) %>%
kable_styling(latex_options = c('hold_position')) %>%
footnote(general=c(fn1, fn2),general_title="",threeparttable = T)
mydf %>%
kable(format='latex',booktabs=T,
col.names=c('X','Y','Z'),
caption=c('This is pretty close to perfect', 'if I could remove the superscripts')) %>%
kable_styling(latex_options = c('hold_position')) %>%
add_footnote(c(fn1, fn2))
```
A screenshot of the knitted PDF:

setting threeparttable = TRUE as #hao suggested worked for me:
add_footnote(c(fn1, fn2), threeparttable = TRUE)

Below is the notation="none" option #hao suggested. It is center-justified.
mydf %>%
kable(format='latex',booktabs=T,
col.names=c('X','Y','Z'),
caption=c('Notation="none"') %>%
kable_styling(latex_options = c('hold_position')) %>%
add_footnote(c(fn1, fn2), notation="none")

Related

KableExtra: colortbl's \cellcolor not filling entire cell when used in combination with \makecell

I'm looking for a workaround solution for a known issue where \cellcolor from the colortbl package does not work properly with \makecell. As mentioned, there probably already exists a workaround in Latex, but I'm hoping for a solution in terms of the R package kableExtra when producing pdfs using rmarkdown. Here's a screenshot; as can be seen, some cells are not filled entirely.
Here's a minimally reproducible example in rmarkdown:
library(kableExtra)
library(tidyverse)
# Data --------------------------------------------------------------------
df <- tribble(
~col1, ~col2,
"really long text that needs to be broken into multiple lines so it can fit", 4,
"really long text that needs to be broken", 4,
"really long text that needs a fix", 4,
) %>%
modify_at(
.x = .,
.at = 1,
.f = stringr::str_wrap,
width = 25
)
# Table -------------------------------------------------------------------
df %>%
mutate(across(.cols = 1, .fns = linebreak, align = "l")) %>%
kbl(x = ., escape = FALSE) %>%
row_spec(row = 1:3, background = "#e5e5e5")
One possible fix is to specify keep_tex: true in the YAML and fix the issue in the .tex file manually before using pandoc. But I'm generating many tables and this can't possibly be efficient. Any suggestion of a potential workaround would be greatly appreciated.
Why not use column_spec to force the line wrap rather than using makecell and linewrap?...
library(tibble)
library(dplyr) #for the pipe
library(kableExtra)
df <- tribble(
~col1, ~col2,
"really long text that needs to be broken into multiple lines so it can fit", 4,
"really long text that needs to be broken", 4,
"really long text that needs a fix", 4,
)
kbl(df) %>%
column_spec(1, width = "30mm") %>%
row_spec(row = 1:3, background = "#e5e5e5")
Another solution that worked for my use case (where column_spec(width) fails), is based on leandriis's comment in this post. Specifically, we wrap the \colorbox command around the \makecell command to have a completely colored cell. For example \colorbox[HTML]{hexcode}{\makecell{text}}. This requires that we create our own custom linebreak function, which not only wraps our text in \makecell but also wraps that latex code in a \colorbox.
# Custom linebreak --------------------------------------------------------
linebreak_custom <- function(x, align = "l", linebreaker = "\n") {
ifelse(
# If '\n' is detected in a string, TRUE, or else FALSE
test = str_detect(x, linebreaker),
# For TRUE's, wrap text in \makecell and then in \colorbox
yes = paste0(
"\\cellcolor[HTML]{e5e5e5}{\\colorbox[HTML]{e5e5e5}{\\makecell[", align, "]{",
str_replace_all(x, linebreaker, "\\\\\\\\"), "}}}"
),
# Return as is if no '\n' detected
no = x
)
}
# Data --------------------------------------------------------------------
df <- tribble(
~col1, ~col2,
"really long text that needs to be broken into multiple lines so it can fit", 4,
"really long text that needs to be broken", 4,
"really long text that needs a fix", 4,
) %>%
modify_at(
.x = .,
.at = 1,
.f = stringr::str_wrap,
width = 25
)
# Table -------------------------------------------------------------------
df %>%
mutate(across(.cols = 1, .fns = linebreak_custom, align = "l")) %>%
kbl(x = ., escape = FALSE) %>%
row_spec(row = 1:3, background = "#e5e5e5")
This produces the desired output:
As noted, this solution may not be robust to future versions of kableExtra (as it involves, quite frankly, "hacking" the source code), and the solution suggested by Peter above should still be better in many use cases. I've created an issue via Github to bring this to their attention, so perhaps there could be an official fix in their code in the future.

Change cell font color in Kable using kableextra, in pdf rmarkdown xelatex

do you know if there is anyway to change the font color of a kable table cell.
it is very important for me to do it with kable or kableextra because I need a stripped table, with some bold columns or rows, but I also need some cells to be in another color. This is the code I would like to extend not to modify if possible
library(kableExtra)
x_latex <- knitr::kable(head(mtcars), "latex", booktabs=T, col.names = NULL)
#kable_styling(x_latex, latex_options = "striped", position = "float_left")
kable_styling(x_latex, latex_options = c("striped","HOLD_position"), stripe_color = "gray!13") %>%
sub("\\\\toprule", "", .) %>%
sub("\\\\bottomrule", "", .) %>% row_spec(2,bold=TRUE)
now lets say rows 1, 1 and 2, 2 need to be red, how could I achieve this? Can I use cell_spec?
Thanks in advance.

kableExtra : How can i set to bold the biggest value of the row?

Suppose i have a table that looks like :
x = matrix(runif(10*5),nrow=10,ncol=5)
When i display the matrix using kableextra, i want the highest value, per row, of say the last 2 rows, to be bolded.
I looked at this document https://rdrr.io/cran/kableExtra/f/inst/doc/awesome_table_in_pdf.pdf a lot and i did not found how to use cell_spec correctly to perform this goal.
I thought this would be easier than it turned out to be. As far as I can see, this is how to do it:
---
title: "Untitled"
output: pdf_document
---
```{r}
set.seed(123)
library(knitr)
library(kableExtra)
x <- matrix(round(runif(10*5),2), nrow=10,ncol=5)
j1 <- which.max(x[9,])
j2 <- which.max(x[10,])
col <- seq_len(ncol(x))
x[9,] <- x[9,] %>% cell_spec(bold = col == j1)
x[10,] <- x[10,] %>% cell_spec(bold = col == j2)
x %>% kable(booktabs = TRUE, escape = FALSE)
```
A few notes:
I rounded the values so they aren't so ugly when printed.
I couldn't see a way to do everything in one pipeline, though there probably is one. The trouble is that cell_spec is designed to work on vectors, not matrices.
Finally, the escape = FALSE in kable() is essential: otherwise you'll see the code to make it bold, rather than the bold entry itself.

Superscript when output to MS Word

It is very easy to do superscript in SAS in headers/footnotes or in a dataset. And it is very useful feature in clinical reporting! Unfortunately, I cannot find it in R.
Now I'm using officer and flextable packages for outputing to MS Word. Is it possible to do superscript and subscript in these packages (or maybe in other packages with similar functionality, like htmlTable?
Yes you can include header and footers using office package
library(officer)
my_doc <- read_docx()
my_doc <- my_doc %>%
body_add_par("Header 1 ", style = "centered") %>%
body_add_par("Header 2 ", style = "centered") %>%
body_add_par("Header 3 ", style = "centered") %>%
body_add_par("Header 4", style = "Normal") %>%
body_add_table(dataframe, style = "Normal Table") %>%
cursor_forward() %>%
body_add_par("Footer 1,
OTH=Other", style = "toc 1") %>%
body_end_section(landscape = TRUE)
print(my_doc, target = "output.docx")
please provide an example of data you want to apply super and subscript to.
In general you can use latex markup with .rmd files and render it to word file like:
$$text_{subscript}$$
$$text^{superscript}$$

tables rmarkdown cellpadding

I am trying to make a table using either hwrite or xtable in rmarkdown to produce a html table. I have been unable to use a cellpadding or cellspacing option, this is the code I am using and attached is a photo of the output.
{r, echo = FALSE, results = 'asis'}
cat(hwrite(sd.m.table, row.names = FALSE, cellpadding = 10, row.style = list("font-weight:bold")))
Using xtable() similarly did not work as well. Does anyone have suggestions?
Generated output from code
I'm not familiar with the hwriter package, and I rarely use xtable anymore (because I get frustrated with customizing tables), so I can't give you specific advice on using those.
I'm most comfortable with pixiedust (because I wrote it), but the htmlTable and tableHTML packages produce nice HTML tables and are probably worth looking into as well.
Working example with pixiedust
---
title: "Untitled"
output: html_document
---
```{r}
library(pixiedust)
head(mtcars) %>%
dust() %>%
sprinkle(pad = 10) %>%
medley_all_borders()
```
EDIT:
To get the appearance you are seeking with your data, try using
library(pixiedust)
library(dplyr)
DF <-
data.frame(rep_complete_time = c("2017-01-04 08:58:22",
"2017-01-04 08:58:33",
"2017-01-06 11:35:28"),
result = c(4.99184, 4.07356, 5.01569),
body_fluid = c("Serum", "Serum", "Serum"),
result_type = c("QC", "QC", "QC"),
fluid_lot = c(4426, 4426, 4426),
level = c(1, 1, 1))
DF %>%
# for some reason, sprintf results aren't holding when used in a
# sprinkle. This seems like a bug in pixiedust.
mutate(result = sprintf("%0.1f", result)) %>%
dust() %>%
sprinkle_colnames("Rep Complete Time", "Result", "Body Fluid",
"Result Type", "Fluid Lot", "Level") %>%
# use part = "table" to apply borders to all parts of the table.
# by default, pixiedust only wants to work with the body of the table.
medley_all_borders(part = "table") %>%
# using the sprinkle_table function can apply sprinkles to all of the
# parts of a table.
sprinkle_table(pad = 10,
halign = "left")
I wasn't able to replicate your alignment problem. All of the columns in my results are aligned left.

Resources