Reputation: 161
I want to modify the format of a portion of a cell, while leaving the remaining text unmodified for inclusion in a .docx report:
e.g., Brill (Scophthalmus rhombus) in subdivisions 22-32 (Baltic Sea)
My data is set up with HTML tags, which I have been trying to modify using the display()
function. My example (somewhat obviously) modifies the entire cell. I expect that the pattern
argument can be modified with {{moustaches}}
to make the nested formatting possible, but I haven't had any luck.
library(flextable)
library(officer)
library(dplyr)
data <- structure(list(Description = c("Brill (<em>Scophthalmus rhombus</em>) in subdivisions 22-32 (Baltic Sea)",
"Cod (<em>Gadus morhua</em>) in subdivisions 22-24, western Baltic stock (western Baltic Sea)",
"Cod (<em>Gadus morhua</em>) in subdivisions 25-32, eastern Baltic stock (eastern Baltic Sea)",
"Dab (<em>Limanda limanda</em>) in subdivisions 22-32 (Baltic Sea)",
"Flounder (<em>Platichthys flesus</em>) in subdivisions 22 and 23 (Belt Seas and the Sound)",
"Flounder (<em>Platichthys flesus</em>) in subdivisions 24 and 25 (west of Bornholm and southwestern central Baltic)"),
SpeciesScientificName = c("Scophthalmus rhombus", "Gadus morhua", "Gadus morhua", "Limanda limanda", "Platichthys flesus", "Platichthys flesus")),
.Names = c("Description", "SpeciesScientificName"),
row.names = c(NA, 6L), class = "data.frame")
data %>%
mutate(Description = gsub("<em>.*?</em>", "%s", Description)) %>%
flextable() %>%
display(col_key = "Description", pattern = "{{sp_italics}}",
formatters = list(sp_italics ~ sprintf(Description, SpeciesScientificName)),
fprops = list(sp_italics = fp_text(italic = TRUE)))
Upvotes: 4
Views: 1845
Reputation: 21
Here is an update to the answer based on the new functions in flextable
(I tried this solution and display()
is deprecated).
I also used set_table_properties(layout = "autofit")
instead of autofit()
, as autofit()
gave me a table that extended outside the margins in the .docx (SO explanation here).
data <- structure(
list(id = c(
"Brill", "Cod", "Cod", "Dab", "Flounder", "Flounder"
), SpeciesScientificName = c(
"Scophthalmus rhombus",
"Gadus morhua", "Gadus morhua", "Limanda limanda", "Platichthys flesus",
"Platichthys flesus"
), subdivision = c(
"22-32", "22-24, western Baltic stock",
"25-32, eastern Baltic stock", "22-32", "22 and 23", "24 and 25"
), location = c(
"Baltic Sea", "western Baltic Sea", "eastern Baltic Sea",
"Baltic Sea", "Belt Seas and the Sound", "west of Bornholm and southwestern central Baltic"
)),
class = "data.frame", .Names = c("id", "SpeciesScientificName", "subdivision", "location"),
row.names = c(NA, -6L)
)
ft <- data %>%
flextable(col_keys = c("dummy_col", "SpeciesScientificName")) %>%
flextable::mk_par(
j = "dummy_col",
value = as_paragraph(
id,
" (", as_i(SpeciesScientificName), ") in ",
location,
" (",
as_chunk(location, props = fp_text_default(color = "red")), ")"
)
) %>%
set_header_labels(
dummy_col = "whatever",
SpeciesScientificName = "SpeciesScientificName"
) %>%
set_table_properties(layout = "autofit")
print(ft, preview = "docx")
Upvotes: 2
Reputation: 378
There may be an easier solution. Using ftExtra
and colformat_md()
will let you do markdown formatting (though it doesn't seem to allow plain HTML)
https://ardata-fr.github.io/flextable-book/extensions.html#ftextra
library(ftExtra)
data.frame(x = c("**bold**", "*italic*"),
y = c("^superscript^", "~subscript~"),
z = c("***^ft^~Extra~** is*", "*Cool*")) %>%
flextable() %>%
colformat_md()
Upvotes: 3
Reputation: 10675
The display function is defining displayed values. It does not allow to format only a portion a of text in a cell, it defines the paragraph content and its formatting. I would start from a tidy data.frame.
data <- structure(list(id = c("Brill", "Cod", "Cod", "Dab", "Flounder",
"Flounder"), SpeciesScientificName = c("Scophthalmus rhombus",
"Gadus morhua", "Gadus morhua", "Limanda limanda", "Platichthys flesus",
"Platichthys flesus"), subdivision = c("22-32", "22-24, western Baltic stock",
"25-32, eastern Baltic stock", "22-32", "22 and 23", "24 and 25"
), location = c("Baltic Sea", "western Baltic Sea", "eastern Baltic Sea",
"Baltic Sea", "Belt Seas and the Sound", "west of Bornholm and southwestern central Baltic"
)), class = "data.frame", .Names = c("id", "SpeciesScientificName", "subdivision", "location"),
row.names = c(NA, -6L))
> data
id SpeciesScientificName subdivision
1 Brill Scophthalmus rhombus 22-32
2 Cod Gadus morhua 22-24, western Baltic stock
3 Cod Gadus morhua 25-32, eastern Baltic stock
4 Dab Limanda limanda 22-32
5 Flounder Platichthys flesus 22 and 23
6 Flounder Platichthys flesus 24 and 25
location
1 Baltic Sea
2 western Baltic Sea
3 eastern Baltic Sea
4 Baltic Sea
5 Belt Seas and the Sound
6 west of Bornholm and southwestern central Baltic
Your example is concatenating 4 informations in one paragraph, the argument formatters
will require 4 arguments...
ft <- data %>%
flextable(col_keys = c("dummy_col", "SpeciesScientificName")) %>%
display(col_key = "dummy_col", pattern = "{{id_}} ({{sciname_}}) in {{subdivision_}} ({{location_}})",
formatters = list(id_ ~ id, sciname_ ~ SpeciesScientificName, subdivision_ ~ subdivision, location_ ~ location ),
fprops = list(sciname_ = fp_text(italic = TRUE), location_ = fp_text(color="red") )) %>%
set_header_labels(dummy_col="whatever") %>%
theme_booktabs() %>% autofit()
read_docx() %>% body_add_flextable(ft) %>% print("test.docx")
Upvotes: 6