Site icon R-bloggers

flextable supports RTF

[This article was first published on R on ArData, and kindly contributed to R-bloggers]. (You can report issue about the content on this page here)
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.
  • Version 0.9 of the ‘flextable’ package adds the possibility to produce tables in RTF documents.

    This format is rare but mandatory for some communities, i.e. mainly in the pharmaceutical industry to our knowledge.

    Usages

    Two methods can be used to embed flextables in an RTF file.

    You can use the save_as_rtf() function which produces an RTF file from one or more flextables. The save_as_rtf() function is a utility function of the `flexable’ package. The documentation of the function can be found at at this address: https://davidgohel.github.io/flextable/reference/save_as_rtf.html.

    If the output is not adapted to your needs, you can use the functions in the ‘officer’ package dedicated to RTF file production, i.e. officer::rtf_doc() and officer::rtf_add(). The documentation for rtf_add() can be found at this address: https://davidgohel.github.io/officer/reference/rtf_add.html.

    In the following we will show the use of save_as_rtf() and the result produced.

    The table for the illustration

    The French news has highlighted some public datasets about the prime ministers of the fifth republic and the uses of the 49-3 article. We have experimented with the data to produce a simple table with flextable.

    The data can be downloaded in rds format as well as the script allowing to obtain these data: src-history-49-3.R.

    x <- readRDS("history-49-3.RDS")
    head(x)
    #>   couleur              name n_nominations      debut        fin duration
    #> 1    CENT   Élisabeth Borne             1 2022-05-16 2023-03-25      313
    #> 2    CENT       Jean Castex             1 2020-07-03 2022-05-16      682
    #> 3    CENT  Édouard Philippe             2 2017-05-15 2020-07-03     1145
    #> 4     GAU Bernard Cazeneuve             1 2016-12-06 2017-05-10      155
    #> 5     GAU      Manuel Valls             2 2014-03-31 2016-12-06      981
    #> 6     GAU Jean-Marc Ayrault             2 2012-05-15 2014-03-31      685
    #>   n_eng_resp n_text n_censor_motion
    #> 1         11      3              14
    #> 2         NA     NA              NA
    #> 3          1      1               2
    #> 4         NA     NA              NA
    #> 5          6      2               3
    #> 6         NA     NA              NA

    Preparation

    First we declare some general settings for flextable.

    set_flextable_defaults(
        .family = "Open Sans", .color = "#333333",
        big.mark = "", fmt_date = "%Y", na_str = "",
        theme_fun = theme_vanilla)

    The political side of the minister is indicated with a circle whose color is the color generally used in the media. These shapes must be prepared first, the ‘grid’ package is used for this.

    library(grid)
    library(dplyr)
    x$couleur <- mapply(function(z) {
      col <- case_when(
        z %in% "GAU" ~ "#FF8080",
        z %in% "DTE" ~ "#143c77",
        z %in% "CENT" ~ "#ff9900",
        TRUE ~ "transparent"
      )
      circleGrob(gp = gpar(fill = col, col = "transparent"))
    }, z = x$couleur, SIMPLIFY = FALSE, USE.NAMES = FALSE)

    The flextable

    Now we can define the table with the functions of ‘flextable’.

    z <- flextable(
      data = x, 
      col_keys = c("name", "couleur", "exercice", "n_eng_resp", "n_text", "n_censor_motion")) |> 
      mk_par(j = "exercice", 
             value = as_paragraph(
               as_i(debut), as_i("-"), as_i(fin),
               as_i(as_bracket(duration, p = " (", s = " jours)")))) |> 
      mk_par(j = "couleur", value = as_paragraph(grid_chunk(couleur, width = .15, height = .15))) |> 
      align(j = "name", align = "right", part = "all") |>
      align(j = c("n_eng_resp", "n_text", "n_censor_motion"), align = "center", part = "all") |>
      set_header_labels(name = "Premier ministre",
                        period = "Période",
                        couleur = "",
                        n_eng_resp = "Recours\nau 49-3",
                        n_text = "Textes\nconcernés",
                        n_censor_motion = "Motions\nde censure",
                        longeur = "Nombre de jours\nen fonction") |> 
      autofit() |> 
      width(j = "couleur", width = .3)
    z

    Premier ministre

    Recours
    au 49-3

    Textes
    concernés

    Motions
    de censure

    Élisabeth Borne

    20222023 (313 jours)

    11

    3

    14

    Jean Castex

    20202022 (682 jours)

    Édouard Philippe

    20172020 (1145 jours)

    1

    1

    2

    Bernard Cazeneuve

    20162017 (155 jours)

    Manuel Valls

    20142016 (981 jours)

    6

    2

    3

    Jean-Marc Ayrault

    20122014 (685 jours)

    François Fillon

    20072012 (1820 jours)

    Dominique de Villepin

    20052007 (712 jours)

    1

    1

    0

    Jean-Pierre Raffarin

    20022005 (1121 jours)

    2

    2

    2

    Lionel Jospin

    19972002 (1799 jours)

    Alain Juppé

    19951997 (747 jours)

    2

    2

    2

    Édouard Balladur

    19931995 (773 jours)

    1

    1

    1

    Pierre Bérégovoy

    19921993 (361 jours)

    3

    3

    1

    Edith Cresson

    19911992 (323 jours)

    8

    4

    2

    Michel Rocard

    19881991 (1100 jours)

    28

    13

    5

    Jacques Chirac

    19861988 (782 jours)

    8

    7

    7

    Laurent Fabius

    19841986 (611 jours)

    4

    2

    1

    Pierre Mauroy

    19811984 (1153 jours)

    7

    5

    6

    Raymond Barre

    19761981 (1722 jours)

    8

    5

    13

    Jacques Chirac

    19741976 (821 jours)

    Pierre Messmer

    19721974 (691 jours)

    Jacques Chaban-Delmas

    19691972 (1111 jours)

    Maurice Couve de Murville

    19681969 (345 jours)

    Georges Pompidou

    19621968 (2279 jours)

    6

    2

    4

    Michel Debré

    19591962 (1192 jours)

    4

    2

    4

    Annotations

    It only remains to add some annotations and the table can be sent in an RTF document.

    z <- add_header_lines(z, 
      values = as_paragraph(
        as_chunk("Historique des recours au 49-3 pendant la V république",
          prop = fp_text_default(.size = 13, bold = TRUE)
        ))
      ) |> 
      footnote(i = 1, j = 1, ref_symbols = "(1)",
               part = "header",
               value = as_paragraph(
                 as_chunk(" source : "),
                 as_i("https://www.assemblee-nationale.fr")
                 )
               ) |> 
      footnote(i = 1, j = 1, ref_symbols = "(2)",
               part = "header",
               value = as_paragraph(
                 as_chunk(" source : "),
                 as_i("https://www.politiquemania.com/longevite-premier-ministre.html")
               )) |> 
      footnote(i = 2, j = c(4, 6), ref_symbols = "(3)",
               part = "header",
               value = as_paragraph(
                 as_chunk("Fréquence ")
               )) |> 
      footnote(i = 2, j = 5, ref_symbols = "(4)", inline = TRUE,
               part = "header",
               value = as_paragraph(
                 as_chunk("Nombre de cas")
               )) |> 
      hline(i = 1, part = "header", border = fp_border_default(width = 0))

    RTF generation

    Because the table is quite large, we use a ‘landscape’ orientation; the header and footer are also augmented with some information including automatic page numbering.

    These settings are made with the officer::prop_section() function.

    library(officer)
    
    sect_properties <- prop_section(
      page_size = page_size(
        width = 8.3, height = 11.7, orient = "landscape"
      ),
      header_default = block_list(fpar("flextable and RTF")),
      footer_default = block_list(fpar("page ", run_word_field(field = "PAGE  \\* MERGEFORMAT"))),
      page_margins = page_mar(bottom = .6, top = .6, right = .5, left = .5)
    )

    The call to the save_as_rtf() function finally produces the RTF file.

    save_as_rtf(
      "Recours au 49-3" = z, 
      pr_section = sect_properties,
      path = "49-3.rtf")

    The result can be seen below:

    overview of 49-3.rtf

    To leave a comment for the author, please follow the link and comment on their blog: R on ArData.

    R-bloggers.com offers daily e-mail updates about R news and tutorials about learning R and many other topics. Click here if you're looking to post or find an R/data-science job.
    Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.
  • Exit mobile version