Search code examples
rcolorsflextableitalic

Italic and color in an R flextable


I have a table containing the presence (+) of species (lines) according to years (columns).

The idea is to italicize the Latin name of each species and to color the lines according to a certain characteristic of the species. Unfortunately, I can't do both at the same time.

The first thing I managed to get is the right color for each line:

library(dplyr)
library(flextable)

mydata <- data.frame(Espèce = c("Acipenser Sturio (L. 1758) Esturgeon européen",
"Alosa alosa  (L.1758) Alose vraie", "Alosa fallax (Lac. 1803) Alose feinte",
"Anguilla anguilla  (L. 1758) Anguille", "Lampetra fluviatilis  (L. 1758) Lamproie de rivière",
"Liza ramada (Risso 1826) Mulet porc") , 
`00` = c("",  "+", "+", "+", "",  "+"), 
`01` = c("",  "+", "+", "+", "+", "+"))


flextable(mydata) %>%
  color(color = c(rep("firebrick2",2),rep("black",3),rep("dodgerblue3",1)))


And when I try to add the italic font (the text before the open bracket), words in italic lose the color previously defined:

mydata %>%
  flextable(col_key=c("dummy_col",names(mydata)[-1])) %>%
  color(color=c(rep("firebrick2",2),rep("black",3),rep("dodgerblue3",1)), part="body")%>%
  display(col_key = "dummy_col", pattern = "{{id_}} ({{sciname_}}",
          formatters = list(id_ ~ unlist(strsplit(paste(mydata$Espèce[1:(length(mydata$Espèce))]), split="\\("))[seq(1,length(unlist(strsplit(paste(mydata$Espèce[1:(length(mydata$Espèce))]), split="\\("))),2)],
                            sciname_ ~ unlist(strsplit(paste(mydata$Espèce[1:(length(mydata$Espèce))]), split="\\("))[seq(2,length(unlist(strsplit(paste(mydata$Espèce[1:(length(mydata$Espèce))]), split="\\("))),2)]),
          fprops = list(id_ =fp_text(italic = TRUE))) %>%
  color(j="dummy_col", color=c(rep("firebrick2",2),rep("black",3),rep("dodgerblue3",1)))

Would you have any suggestion to get both at the same time, namely the italicized text in the right color?


Solution

  • Yes, you can use the following code to get what you want:

    library(dplyr)
    library(tidyr)
    library(flextable)
    
    mydata <- data.frame(Espèce = c("Acipenser Sturio (L. 1758) Esturgeon européen",
                                    "Alosa alosa  (L.1758) Alose vraie", "Alosa fallax (Lac. 1803) Alose feinte",
                                    "Anguilla anguilla  (L. 1758) Anguille", "Lampetra fluviatilis  (L. 1758) Lamproie de rivière",
                                    "Liza ramada (Risso 1826) Mulet porc") , 
                         `X00` = c("",  "+", "+", "+", "",  "+"), 
                         `X01` = c("",  "+", "+", "+", "+", "+")) %>% 
      separate(`Espèce`, c("latin_name", "french_name"), sep = "\\(") %>% 
      mutate(french_name = paste0("(", french_name) )
    

    The original column should be split in two column so that it's easier to reuse.

    > mydata
                  latin_name                   french_name X00 X01
    1      Acipenser Sturio   (L. 1758) Esturgeon européen        
    2          Alosa alosa            (L.1758) Alose vraie   +   +
    3          Alosa fallax       (Lac. 1803) Alose feinte   +   +
    4    Anguilla anguilla              (L. 1758) Anguille   +   +
    5 Lampetra fluviatilis   (L. 1758) Lamproie de rivière       +
    6           Liza ramada        (Risso 1826) Mulet porc   +   +
    

    Then by using function compose, as_paragraph and as_i (as italic), you can get what you want:

    flextable(mydata, col_keys = c("dummy", "X00", "X01")) %>%
      compose(j = "dummy", value = as_paragraph(as_i(latin_name), french_name)) %>% 
      color(color=c(rep("firebrick2",2),rep("black",3),rep("dodgerblue3",1)), part="body") %>% 
      autofit()
    
    

    enter image description here

    Note that function display will be deprecated and should be replaced by compose.