I have the following table generated in RMarkdown using the kableExtra package. I'm trying to bold selected words in a cell (the word First in my example below) and force a linebreak between two words in a cell (First and Message), however this doesn't seem to work. Any ideas on how to do this?
library(kableExtra)
library(tidyverse)
first <- c('\\textbf{First} Message','\\textbf{First}\n Message','First Message')
second <- c('Second Message','Second Message','Second Message')
third <- c('Third Message','Third Message','Third Message')
data.frame(first,second,third) %>%
kable(format='latex',caption="Caption",
col.names = c('First',"Second","Third"), booktabs = T, escape = FALSE) %>%
kable_styling(latex_options = c("HOLD_position"), font_size = 7) %>%
row_spec(0,bold=T,color = 'white', background = '#7c3042')
You need to add mutate_all(linebreak) %>% to your code.
Check the documentation here (page 26): https://haozhu233.github.io/kableExtra/awesome_table_in_pdf.pdf
Modifying your code:
library(kableExtra)
library(tidyverse)
first <- c('\\textbf{First} Message','\\textbf{First}\n Message','First Message')
second <- c('Second Message','Second Message','Second Message')
third <- c('Third Message','Third Message','Third Message')
data.frame(first,second,third) %>%
mutate_all(linebreak) %>%
kable(format='latex',caption="Caption",
col.names = c('First',"Second","Third"), booktabs = T, escape = FALSE) %>%
kable_styling(latex_options = c("HOLD_position"), font_size = 7) %>%
row_spec(0,bold=T,color = 'white', background = '#7c3042')
Result:
Related
Problem
Code
# Toy Data
ID <- c(paste("G0", as.character(1:9), sep = ""),"G10","G11","Mean")
V1 <- c(10.06,11.06,12.06,13.06,14.06,15.06,16.06,17.07,18.07,19.07,6.88,13.86)
V2 <- c(0.21,0.03,0.09,0.03,0.09,0.03,0.09,0.03,0.09,0.21,0.31,NA)
tbl <- data.frame(ID, V1, V1, V2, V1, V2, V1, V2, V2)
colnames(tbl) <- c('ID','Get. \\%','Get. \\%','K','Get. \\%','K','Get. \\%','K','P')
# Specify kable NA value and load kableExtra
options(knitr.kable.NA = '--')
require(kableExtra)
# Generate table for PDF output (LaTeX)
kbl(tbl, format = 'latex', align = 'l', booktabs = T, escape = F, digits = 2,
linesep = "", caption = "This is a table caption.") %>%
add_header_above(c(" ", "AB", "BP" = 2, "CK" = 2, "JAM" = 2, ""), bold = T) %>%
column_spec(1, width = '1.15cm') %>%
row_spec(11, hline_after = T) %>%
row_spec(12, bold = T) %>%
kable_styling(position = "center", latex_options = "hold_position") %>%
footnote(general_title = "Note.", footnote_as_chunk = T,
general = "Relatively long footnote that I would like to span
a couple of lines. Relatively long footnote that I
would like to span a couple of lines.")
Output
Comments
Issue 1: The output displays 'makecell[1]' in the footnote, which I obviously do not want included. Adding the argument escape = T did not resolve this problem as I expected it might have.
N.B. By setting footnote_as_chunk = F, this issue was resolved, but with the unwanted effect of introducing a line break before the caption starts. This is demonstrated by Peter's answer below.
Issue 2 The footnote does not want to be constrained to the length of the table. I suppose one might be able to manually add line breaks in the footnote string, but this seems like tedious work-around, and I'm hoping there is a method for achieving this more efficiently. The documentation shows (see Table 4, p. 25) an example of how one might circumvent this problem, but the code is absent.
EDIT: This issue (#2) was resolved by setting threeparttable = T when calling kbl.
Compiling with pdflatex or xelatex does not seem to make any difference. Any insight would be much appreciated.
Try this:
library(kableExtra)
library(magrittr)
kbl(tbl,
format = 'latex',
longtable = TRUE,
align = 'l',
booktabs = T,
escape = F,
digits = 2,
linesep = "",
caption = "This is a table caption.") %>%
add_header_above(c(" ", "AB", "BP" = 2, "CK" = 2, "JAM" = 2, ""), bold = T) %>%
column_spec(1, width = '1.15cm') %>%
row_spec(11, hline_after = T) %>%
row_spec(12, bold = T) %>%
kable_styling(position = "center", latex_options = "hold_position", full_width = FALSE) %>%
footnote(general_title = "Note.",
footnote_as_chunk = TRUE,
threeparttable = TRUE,
general = "Relatively long footnote that I would like to span a couple of lines. Relatively long footnote that I would like to span a couple of lines.")
With footnote_as_chunk = TRUE using the "general" footnote option "Note." and the "Footnote...." text start on the same line. As in this example, image below.
Hei,
To compare several variants of data I produced a HTML report.
Given a special catagory some indexes in the database should be the same. To detect errors / incorrect entries in the database I compare the different categories in a table.
For better reading, it would be fine, to have coloured tables. This can be done easily with the formattable-Package.
My dataset:
require(tidyverse)
require(formattable)
require(kableExtra)
require(knitr)
df1 <- data.frame(V1 = c(68,sample(c("J","N"),size=15,replace = TRUE)),
V2 = c(10,sample(c("J","N"),size=15,replace = TRUE)),
V3 = c(1,sample(c("J","N"),size=15,replace = TRUE))
)
It has - in this example - 3 differnt variants. Only one is recomended. It is supposed, that the variant with the highest N (=first entry in each Vx-Column) is the real one.
My formated table is produced with this code:
df1 %>%
mutate(
V2 = ifelse((as.character(V2) == as.character(V1)) == FALSE,
cell_spec(V2, color = "red",bold = TRUE),
cell_spec(V2, color = "black",bold = FALSE)),
V3 = ifelse((as.character(V3) == as.character(V1)) == FALSE,
cell_spec(V3, color = "red",bold = TRUE),
cell_spec(V3, color = "black",bold = FALSE))
) %>%
kable(format = "html", escape = FALSE) %>%
kable_styling(c("striped", "condensed"), full_width = FALSE) %>%
row_spec(1, bold = T, color = "white", background = "#D7261E")
Two questions:
How to mutate in a loop?
This is necessary because the different categories I have to investigate can have up to 18 different variants. In each dataset, V1 is everytime the reference variant.
As you can see (run the code!) the first line (the "N"s) is coded in the wrong matter. Is it possible to compare from the second line on only (first line is set to TRUE by default)
This would be fine, because the first line is now formated in a matter that does not really make sense.
Thank you!
To answer your two questions:
Instead of looping over the columns, you can use mutate_all
Just take a copy of the first column and mutate it back in later
I have first made your cell_spec calls into functions to reduce clutter in the code.
red <- function(x) cell_spec(x, color = "red", bold = TRUE)
black <- function(x) cell_spec(x, color = "black", bold = FALSE)
c1 <- as.character(df1[[1]])
Now we can do this:
df1 %>%
select(-V1) %>%
mutate_all(function(x) ifelse(as.character(x) != df1[[1]], red(x), black(x))) %>%
mutate(V1 = black(c1)) %>%
mutate_all(function(x) `[<-`(x, 1, " ")) %>%
select(V1, V2, V3) %>%
kable(format = "html", escape = FALSE) %>%
kable_styling(c("striped", "condensed"), full_width = FALSE) %>%
row_spec(1, bold = T, color = "white", background = "#D7261E")
Which gives this result:
Thank you, #AllanCameron!
I 'm not familiar to the package purrr - I really should do more studies about it.
Your idea with purrr::map_dfc solved the problem.
Instead of the first column I need the first row (the digit-row), and of course with grepl it is possible to solve this. The condition in the ifelse-Statement is a little bit longer then.
My final solution is then:
df1 %>%
map_dfc(function(x) ifelse(as.character(x) != as.character(df1$V1) & !grepl("[[:digit:]]",x),
mark_true(x), mark_false(x))) %>%
select(V1, everything()) %>%
kable(format = "html", escape = FALSE) %>%
kable_styling(c("striped", "condensed"), full_width = FALSE) %>%
row_spec(1, bold = T, color = "white", background = "#D7261E")
Thank you very much!
In Rmd knit to pdf we found out we can end a table with a double line like this:
tibble(v1 = c(1:2),v2 = c(1:2)) %>%
kable(booktabs = TRUE) %>%
kable_styling(position = "left") %>%
row_spec(2, hline_after = TRUE) %>%
row_spec(3, hline_after = TRUE)
When we want to use this for a table that continues on the next page, with use of:
tibble(v1 = c(1:2),v2 = c(1:2)) %>%
kable(booktabs = TRUE, longtable = TRUE) %>%
kable_styling(latex_options = c("repeat_header"),
position = "left") %>%
row_spec(2, hline_after = TRUE) %>%
row_spec(3, hline_after = TRUE)
we see an unwanted * between the two lines. Does anyone know why the * appears, or have a suggestion how to get rid of the *, or a better solution to have a double line at the end of a table? Thanks!
I am formatting a table using formattable:color_bar and would like to add a comma as a thousands separator as well as adjust the colour of the font.
For cells where I don't use color_bar I see how I can use cell_spec to change the font color but I don't know how to do it with cells that are using color_bar.
library(tidyverse)
library(knitr)
library(kableExtra)
library(formattable)
df <- tibble (
rank = c(1,2,3),
tree = c("Norway Maple", "Honey Locust", "Colorado Blue Spruce"),
number = c(74688, 24286, 21917)
)
df %>%
mutate(
tree = cell_spec(tree, "html", color = "black"),
number = color_bar()(number)) %>%
kable("html", escape = F, align = c("l", "l")) %>%
kable_styling(bootstrap_options = c("hover", "responsive", "condensed"), full_width = F, position = "float_left") %>%
column_spec(3, width = "10cm")
First, the package kableExtra indeed produces awesome table. I just have an additional request :
When running this example ( from the manual)
iris[1:10, ] %>% select(-Species) %>%
mutate_if(is.numeric, function(x) {
cell_spec(x, "latex", bold = T, color = spec_color(x, end = 0.9),
font_size = spec_font_size(x))
}) %>%
kable("latex", escape = F, booktabs = T, linesep = "", align = "c")
The cells are formated in each column. (1) How to adjust them to the entire table ? (2) Or to a user defined scale ? I noticed that both kableExtra::spec_color and
kableExtra::cell_spec make use of the scales::rescale function which does take a from argument but it's not used in the functions.
Below code of reproducible .Rnw script.
\documentclass{article}
\usepackage[usenames,dvipsnames,svgnames,table]{xcolor}
\usepackage{booktabs}
\usepackage{float}
\usepackage{colortbl}
\begin{document}
<<tab10, echo=FALSE, results="as.is">>=
require(knitr)
require(kableExtra)
require(tidyverse)
#
<<tab1, echo=FALSE, results="as.is">>=
require(knitr)
require(kableExtra)
require(tidyverse)
iris[1:10, ] %>% select(-Species) %>%
mutate_if(is.numeric, function(x) {
cell_spec(x, "latex", bold = T, color = spec_color(x, end = 0.9),
font_size = spec_font_size(x))
}) %>%
kable("latex", escape = F, booktabs = T, linesep = "", align = "c")
#
\end{document}
Okay, with the latest dev ver, you can use scale_from in spec_color, spec_font_size & spec_angle.
library(kableExtra)
library(dplyr)
library(knitr)
iris[1:10, ] %>%
select(-Species) %>%
mutate_if(is.numeric, function(x) {
cell_spec(x, "latex", bold = T,
color = spec_color(x, end = 0.9, scale_from = range(unlist(iris[1:10, ]))),
font_size = spec_font_size(x, scale_from = range(unlist(iris[1:10, ]))))
}) %>%
kable("latex", escape = F, booktabs = T, linesep = "", align = "c")