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 ministreRecoursau 49-3TextesconcernésMotionsde censureÉlisabeth Borne2022-2023 (313 jours)11314Jean Castex2020-2022 (682 jours)Édouard Philippe2017-2020 (1145 jours)112Bernard Cazeneuve2016-2017 (155 jours)Manuel Valls2014-2016 (981 jours)623Jean-Marc Ayrault2012-2014 (685 jours)François Fillon2007-2012 (1820 jours)Dominique de Villepin2005-2007 (712 jours)110Jean-Pierre Raffarin2002-2005 (1121 jours)222Lionel Jospin1997-2002 (1799 jours)Alain Juppé1995-1997 (747 jours)222Édouard Balladur1993-1995 (773 jours)111Pierre Bérégovoy1992-1993 (361 jours)331Edith Cresson1991-1992 (323 jours)842Michel Rocard1988-1991 (1100 jours)28135Jacques Chirac1986-1988 (782 jours)877Laurent Fabius1984-1986 (611 jours)421Pierre Mauroy1981-1984 (1153 jours)756Raymond Barre1976-1981 (1722 jours)8513Jacques Chirac1974-1976 (821 jours)Pierre Messmer1972-1974 (691 jours)Jacques Chaban-Delmas1969-1972 (1111 jours)Maurice Couve de Murville1968-1969 (345 jours)Georges Pompidou1962-1968 (2279 jours)624Michel Debré1959-1962 (1192 jours)424 Annotations It only remains to add some annotations and the table can be sent in an RTF document. z 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 " />

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(
    font.family = "Open Sans", font.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

2022-2023 (313 jours)

11

3

14

Jean Castex

2020-2022 (682 jours)

Édouard Philippe

2017-2020 (1145 jours)

1

1

2

Bernard Cazeneuve

2016-2017 (155 jours)

Manuel Valls

2014-2016 (981 jours)

6

2

3

Jean-Marc Ayrault

2012-2014 (685 jours)

François Fillon

2007-2012 (1820 jours)

Dominique de Villepin

2005-2007 (712 jours)

1

1

0

Jean-Pierre Raffarin

2002-2005 (1121 jours)

2

2

2

Lionel Jospin

1997-2002 (1799 jours)

Alain Juppé

1995-1997 (747 jours)

2

2

2

Édouard Balladur

1993-1995 (773 jours)

1

1

1

Pierre Bérégovoy

1992-1993 (361 jours)

3

3

1

Edith Cresson

1991-1992 (323 jours)

8

4

2

Michel Rocard

1988-1991 (1100 jours)

28

13

5

Jacques Chirac

1986-1988 (782 jours)

8

7

7

Laurent Fabius

1984-1986 (611 jours)

4

2

1

Pierre Mauroy

1981-1984 (1153 jours)

7

5

6

Raymond Barre

1976-1981 (1722 jours)

8

5

13

Jacques Chirac

1974-1976 (821 jours)

Pierre Messmer

1972-1974 (691 jours)

Jacques Chaban-Delmas

1969-1972 (1111 jours)

Maurice Couve de Murville

1968-1969 (345 jours)

Georges Pompidou

1962-1968 (2279 jours)

6

2

4

Michel Debré

1959-1962 (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(font.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.

Never miss an update!
Subscribe to R-bloggers to receive
e-mails with the latest R posts.
(You will not see this message again.)

Click here to close (This popup will not appear again)