This vignette introduces how to format columns in flextable.
library(flextable)
library(ftExtra)
The flextable package is an excellent package that allows fine controls on styling tables, and export it to variety of formats (HTML, MS Word, PDF). Especially, when output format is MS Word, this package is the best solution in R.
On the other hand, styling texts with the flextable package often require large efforts. The following example subscripts numeric values in chemical formulas.
<- data.frame(Oxide = c("SiO2", "Al2O3"), stringsAsFactors = FALSE)
df <- flextable::flextable(df)
ft
%>%
ft ::compose(
flextablei = 1, j = "Oxide",
value = flextable::as_paragraph(
"SiO", as_sub("2")
)%>%
) ::compose(
flextablei = 2, j = "Oxide",
value = flextable::as_paragraph(
"Al", as_sub("2"), "O", as_sub("3")
) )
Oxide |
SiO2 |
Al2O3 |
The above example has two problems:
compose
for each cells one by one.compose
, as_paragraph
, and as_sub
in the above exampleThe first point can be solved by using a for
loop, however, the code becomes quite complex.
<- data.frame(Oxide = c("SiO2", "Fe2O3"), stringsAsFactors = FALSE)
df <- flextable::flextable(df)
ft
for (i in seq(nrow(df))) {
<- flextable::compose(
ft i = i, j = "Oxide",
ft, value = flextable::as_paragraph(
list_values = df$Oxide[i] %>%
::str_replace_all("([2-9]+)", " \\1 ") %>%
stringr::str_split(" ", simplify = TRUE) %>%
stringr::map_if(
purrrfunction(x) stringr::str_detect(x, "[2-9]+"),
::as_sub
flextable
)
)
)
} ft
Oxide |
SiO2 |
Fe2O3 |
The ftExtra package provides easy solution by introducing markdown. As markdown texts self-explain their formats by plain texts, what users have to do is manipulations of character columns with their favorite tools such as the famous dplyr and stringr packages.
flextable
function or as_flextable
function.colformat_md
The following example elegantly simplifies the prior example.
<- data.frame(Oxide = c("SiO2", "Fe2O3"), stringsAsFactors = FALSE)
df
%>%
df ::mutate(Oxide = stringr::str_replace_all(Oxide, "([2-9]+)", "~\\1~")) %>%
dplyr::flextable() %>%
flextable::colformat_md() ftExtra
Oxide |
SiO2 |
Fe2O3 |
The colformat_md
function is smart enough to detect character columns, so users can start without learning its arguments. Of course, it is possible to chose columns.
Another workflow is to read a markdown-formatted table from a external file. Again, markdown is by design a plain text, and can easily be embed in any formats such as CSV and Excel. So users can do something like
::read_csv("example.csv") %>%
readr::flextable() %>%
flextable::colformat_md() ftExtra
By default, the ftExtra package employs Pandoc’s markdown, which is also employed by R Markdown. This enables consistent user experience when using the ftExtra package in R Markdown.
The example below shows that colformat_md()
function parses markdown texts in the flextable object.
data.frame(
a = c("**bold**", "*italic*"),
b = c("^superscript^", "~subscript~"),
c = c("`code`", "[underline]{.underline}"),
d = c("*[**~ft~^Extra^**](https://ftextra.atusy.net/) is*",
"[Cool]{.underline shading.color='skyblue'}"),
stringsAsFactors = FALSE
%>%
) as_flextable() %>%
colformat_md()
The table header can also be formatted by specifying part = "header"
or "all"
to colformat_md()
Supported syntax are
code
[foo]{.underline})
[foo]{color=red}
[foo]{shading.color=gray}
[foo]{font.family=Roboto}
Note that other syntax may result in unexpected behaviors. The ftExtra package does not support multiple paragraphs or block elements other than the paragraph.
Currently footnotes have some limitations.
For example,
data.frame(
package = "ftExtra",
description = "Extensions for 'Flextable'^[Supports of footnotes]",
stringsAsFactors = FALSE
%>%
) as_flextable() %>%
colformat_md() %>%
::autofit(add_w = 0.5) flextable
package | description |
ftExtra | Extensions for ‘Flextable’1 |
1Supports of footnotes |
Reference symboles can be configured by footnote_options()
. Of course, markdown can be used inside footnotes as well.
data.frame(
package = "ftExtra^[Short of *flextable extra*]",
description = "Extensions for 'Flextable'^[Supports of footnotes]"
%>%
) as_flextable() %>%
colformat_md(
.footnote_options = footnote_options(ref = "i",
prefix = '[',
suffix = ']',
start = 2,
inline = TRUE,
sep = "; ")
%>%
) ::autofit(add_w = 0.5) flextable
package | description |
ftExtra[ii] | Extensions for ‘Flextable’[iii] |
[ii]Short of flextable extra; [iii]Supports of footnotes |
Images can be inserted optionally with width and/or height attributes. Specifying one of them changes the other while keeping the aspect ratio.
data.frame(
R = sprintf("", system.file("img", "Rlogo.jpg", package="jpeg")),
stringsAsFactors = FALSE
%>%
) as_flextable() %>%
colformat_md() %>%
::autofit() flextable
R |
The R logo is distributed by The R Foundation with the CC-BY-SA 4.0 license.
By default, soft line breaks becomes spaces.
data.frame(linebreak = c("a\nb"), stringsAsFactors = FALSE) %>%
as_flextable() %>%
colformat_md()
linebreak |
a b |
Pandoc’s markdown supports hard line breaks by adding a backslash or double spaces at the end of a line.
data.frame(linebreak = c("a\\\nb"), stringsAsFactors = FALSE) %>%
as_flextable() %>%
colformat_md()
linebreak |
a |
It is also possible to make \n
as a hard line break by extending Pandoc’s Markdown.
data.frame(linebreak = c("a\nb"), stringsAsFactors = FALSE) %>%
as_flextable() %>%
colformat_md(md_extensions = "+hard_line_breaks")
linebreak |
a |
Citations is experimentally supported. Note that there are no citation lists. It is expected to be produced by using R Markdown.
First, create a ftExtra.bib
file like below.
@Manual{R-ftExtra,
title = {ftExtra: Extensions for Flextable},
author = {Atsushi Yasumoto},
note = {https://ftextra.atusy.net, https://github.com/atusy/ftExtra},
year = {2021},
}
Second, specify it within the YAML front matter. It may also be required to cite references in the nocite
field.
---
bibliography: ftExtra.bib
nocite: @R-ftExtra
---
Finally, cite the references within tables.
data.frame(
Cite = c("@R-ftExtra", "[@R-ftExtra]", "[-@R-ftExtra]"),
stringsAsFactors = FALSE
%>%
) as_flextable() %>%
colformat_md() %>%
::autofit(add_w = 0.2) flextable
Cite |
@R-ftExtra |
[@R-ftExtra] |
[-@R-ftExtra] |
The rendering of math is also possible.
data.frame(math = "$e^{i\\theta} = \\cos \\theta + i \\sin \\theta$",
stringsAsFactors = FALSE) %>%
as_flextable() %>%
colformat_md() %>%
::autofit(add_w = 0.2) flextable
math |
eiθ = cos θ + isin θ |
Note that results can be insufficient. This feature relies on Pandoc’s HTML writer, which
render TeX math as far as possible using Unicode characters
https://pandoc.org/MANUAL.html#math-rendering-in-html
Pandoc’s markdown provides an extension, emoji
. To use it with colformat_md()
, specify md_extensions="+emoji"
.
data.frame(emoji = c(":+1:"), stringsAsFactors = FALSE) %>%
as_flextable() %>%
colformat_md(md_extensions = "+emoji")
emoji |
👍 |