Site icon R-bloggers

flextable 0.4.0 is out

[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.
  • The package flextable is existing since mid 2016 and I did not made any communication about it; obviously if I wrote it, I’d like it to be used by R users! That post is an attempt to fix that.

    The flextable package makes it simpler to create tables for reporting purposes. The goal of the package is to provide a set of functions that can be used to design and format tabular reporting.

    It’s been originally written in order to provide an alternative to ReporteRs::FlexTable objects that are not supported by package officer.

    What the flextable package does

    It lets customize tables, their formats and their contents. Formatting can be done on cells, paragraphs and text. It also lets you to insert headers and footer rows with eventually merged cells.

    Common operations can be made with simple functions, i.e. use bold() to make a table selection bold, use align() to set alignment, merge_at() to merge contiguous cells, etc. Conditional formatting is possible with each of these functions.

    < svg style="width: 100%;" viewBox="0 0 716 447"> < rect style="fill:rgba(255, 255, 255, 0);" width="450"> < text x="200" y="239.00" style="fill:rgb(0, 102, 153); -size: 60px;">regulartable < text x="366" y="258.25" style="fill:rgb(0, 102, 153); -size: 15px;">bold < text x="206" y="188.50" style="fill:rgb(0, 102, 153); -size: 30px;">set_header_labels < text x="316" y="260.25" style="fill:rgb(0, 102, 153); -size: 15px;">border < text x="336" y="280.25" style="fill:rgb(0, 102, 153); -size: 15px;">display < text x="318" y="298.25" style="fill:rgb(0, 102, 153); -size: 15px;">merge_h < text x="402" y="262.25" style="fill:rgb(0, 102, 153); -size: 15px;">rotate < text x="314" y="158.25" style="fill:rgb(0, 102, 153); -size: 15px;">padding < text x="366" y="145.85" style="fill:rgb(0, 102, 153); -size: 23px;">style < text x="394" y="282.25" style="fill:rgb(0, 102, 153); -size: 15px;">align < text x="294" y="276.25" style="fill:rgb(0, 102, 153); -size: 15px;">italic < text x="272" y="122.50" style="fill:rgb(0, 102, 153); -size: 30px;">add_header < text x="340" y="323.85" style="fill:rgb(0, 102, 153); -size: 23px;">body_add_flextable < text x="254" y="154.25" style="fill:rgb(0, 102, 153); -size: 15px;">size < text x="306" y="312.25" style="fill:rgb(0, 102, 153); -size: 15px;">bg < text x="332" y="351.85" style="fill:rgb(0, 102, 153); -size: 23px;">ph_with_flextable < text x="254" y="290.25" style="fill:rgb(0, 102, 153); -size: 15px;">color < text x="446" y="267.85" style="fill:rgb(0, 102, 153); -size: 23px;">autofit < text x="272" y="328.25" style="fill:rgb(0, 102, 153); -size: 15px;">merge_at < text x="240" y="270.25" style="fill:rgb(0, 102, 153); -size: 15px;">width < text x="408" y="302.25" style="fill:rgb(0, 102, 153); -size: 15px;">void < text x="440" y="296.25" style="fill:rgb(0, 102, 153); -size: 15px;">merge_v < text x="296" y="91.00" style="fill:rgb(0, 102, 153); -size: 60px;">flextable < text x="362" y="381.85" style="fill:rgb(0, 102, 153); -size: 23px;">knit_print.flextable < text x="262" y="410.50" style="fill:rgb(0, 102, 153); -size: 30px;">set_header_df

    Supported outputs

    These objects can be rendered with R markdown documents. There is a knitr::knit_print method for HTML output and for Word output (thanks to Maxim Nazarov). Note that you will need pandoc >= 2.0.0 if you want to use Word output.

    These objects can also be used with package officer and can be rendered into Word and PowerPoint documents (and Excel when I will find time and motivation for it).

    xtable

    A work started to support outputs from package xtable. It make statistical reporting easier for those used to work with xtable.

    For now, only xtable objects are supported but xtableList will also be supported later.

    library(xtable)
    library(flextable)
    temp.ts <- ts(cumsum(1 + round(rnorm(100), 0)),
      start = c(1954, 7), frequency = 12)
    ft <- xtable_to_flextable(x = xtable(temp.ts, digits = 0),
      NA.string = "-")
    ft

    Jan

    Feb

    Mar

    Apr

    May

    Jun

    Jul

    Aug

    Sep

    Oct

    Nov

    Dec

    1954

    1.000

    2.000

    2.000

    4.000

    6.000

    8.000

    1955

    9.000

    12.000

    13.000

    14.000

    14.000

    13.000

    16.000

    16.000

    17.000

    17.000

    18.000

    17.000

    1956

    19.000

    21.000

    22.000

    22.000

    22.000

    22.000

    25.000

    26.000

    27.000

    27.000

    29.000

    32.000

    1957

    32.000

    33.000

    33.000

    34.000

    35.000

    35.000

    37.000

    36.000

    38.000

    39.000

    39.000

    40.000

    1958

    39.000

    40.000

    41.000

    43.000

    44.000

    45.000

    46.000

    47.000

    48.000

    49.000

    49.000

    51.000

    1959

    52.000

    53.000

    54.000

    55.000

    56.000

    57.000

    56.000

    55.000

    55.000

    57.000

    56.000

    56.000

    1960

    56.000

    58.000

    60.000

    61.000

    63.000

    64.000

    67.000

    69.000

    70.000

    71.000

    73.000

    76.000

    1961

    77.000

    75.000

    77.000

    77.000

    77.000

    79.000

    79.000

    81.000

    81.000

    82.000

    83.000

    84.000

    1962

    85.000

    86.000

    87.000

    88.000

    88.000

    88.000

    89.000

    91.000

    92.000

    93.000

    Preview

    the function print() makes it easier to view the flextable inside all supported format.

    By default, the print method display the flextable in an HTML page, if you are running R with RStudio, the flextable is displayed in the Viewer as an HTML table.

    This can be change with argument preview. The document will be opened with the application associated to the file extension (Word or PowerPoint). This will not work on a Web server, i.e. RStudio Server.

    library(flextable)
    
    ft <- regulartable(head(iris))
    ft <- theme_vanilla(ft)
    ft <- width(ft, width = 1)
    ft

    Sepal.Length

    Sepal.Width

    Petal.Length

    Petal.Width

    Species

    5.1

    3.5

    1.4

    0.2

    setosa

    4.9

    3.0

    1.4

    0.2

    setosa

    4.7

    3.2

    1.3

    0.2

    setosa

    4.6

    3.1

    1.5

    0.2

    setosa

    5.0

    3.6

    1.4

    0.2

    setosa

    5.4

    3.9

    1.7

    0.4

    setosa

    print(ft, preview = "log")
    #> a flextable object.
    #> col_keys: `Sepal.Length`, `Sepal.Width`, `Petal.Length`, `Petal.Width`, `Species` 
    #> header has 1 row(s) 
    #> body has 6 row(s) 
    #> original dataset sample: 
    #>   Sepal.Length Sepal.Width Petal.Length Petal.Width Species
    #> 1          5.1         3.5          1.4         0.2  setosa
    #> 2          4.9         3.0          1.4         0.2  setosa
    #> 3          4.7         3.2          1.3         0.2  setosa
    #> 4          4.6         3.1          1.5         0.2  setosa
    #> 5          5.0         3.6          1.4         0.2  setosa
    print(ft, preview = "docx")
    print(ft, preview = "pptx")

    Detailed example

    Let’s first create a data.frame example from a sample of mtcars. We will use it as data source for our reporting table.

    library(tibble)
    library(magrittr)
    
    dataset <- mtcars %>% 
      rownames_to_column(var = "car_name") %>% 
      head() %T>%
      print()
    #>            car_name  mpg cyl disp  hp drat    wt  qsec vs am gear carb
    #> 1         Mazda RX4 21.0   6  160 110 3.90 2.620 16.46  0  1    4    4
    #> 2     Mazda RX4 Wag 21.0   6  160 110 3.90 2.875 17.02  0  1    4    4
    #> 3        Datsun 710 22.8   4  108  93 3.85 2.320 18.61  1  1    4    1
    #> 4    Hornet 4 Drive 21.4   6  258 110 3.08 3.215 19.44  1  0    3    1
    #> 5 Hornet Sportabout 18.7   8  360 175 3.15 3.440 17.02  0  0    3    2
    #> 6           Valiant 18.1   6  225 105 2.76 3.460 20.22  1  0    3    1

    Now let’s use flextable API:

    myft <- regulartable( dataset, 
      col_keys = c("car_name", "am", "carb", "gear", "blank", "mpg", "drat" )) %>% 
      theme_vanilla() %>% 
      width(j = c("am", "carb", "gear", "mpg", "drat" ), width = 1) %>% 
      width(j = 1, width = 2)
    myft

    car_name

    am

    carb

    gear

    mpg

    drat

    Mazda RX4

    1

    4

    4

    21.0

    3.90

    Mazda RX4 Wag

    1

    4

    4

    21.0

    3.90

    Datsun 710

    1

    1

    4

    22.8

    3.85

    Hornet 4 Drive

    0

    1

    3

    21.4

    3.08

    Hornet Sportabout

    0

    2

    3

    18.7

    3.15

    Valiant

    0

    1

    3

    18.1

    2.76

    We’ve just created a simple table. Let’s customize printed values.

    # Change labels
    myft <- myft %>% 
      set_header_labels(
        car_name = "Car name", am = "Transmission", carb = "# carburetors", 
        gear = "# forward gears", mpg = "Miles/(US) gallon", drat = "Rear axle ratio") 
    myft <- myft %>% 
      add_header(mpg = "Some measures") %>% 
      merge_at(i = 1, j = c("mpg", "drat"), part = "header") %>% 
      set_formatter( 
        am = function(x) ifelse( x < 1, "automatic", "manual"),
        carb = function(x) sprintf("%.0f", x),
        gear = function(x) sprintf("%.0f", x)
        ) 
    myft

    Some measures

    Car name

    Transmission

    # carburetors

    # forward gears

    Miles/(US) gallon

    Rear axle ratio

    Mazda RX4

    manual

    4

    4

    21.0

    3.90

    Mazda RX4 Wag

    manual

    4

    4

    21.0

    3.90

    Datsun 710

    manual

    1

    4

    22.8

    3.85

    Hornet 4 Drive

    automatic

    1

    3

    21.4

    3.08

    Hornet Sportabout

    automatic

    2

    3

    18.7

    3.15

    Valiant

    automatic

    1

    3

    18.1

    2.76

    And now let’s add some formattings.

    myft <- myft %>% 
      bold(i = 3, bold = TRUE) %>% bold(j = 3, bold = TRUE) %>% 
      color(j = 3, color = "#4790b5") %>% color(i = 3, color = "#d24625") %>% 
      align(j = 3:6, align = "center", part = "all") %>% 
      empty_blanks()
    myft

    Some measures

    Car name

    Transmission

    # carburetors

    # forward gears

    Miles/(US) gallon

    Rear axle ratio

    Mazda RX4

    manual

    4

    4

    21.0

    3.90

    Mazda RX4 Wag

    manual

    4

    4

    21.0

    3.90

    Datsun 710

    manual

    1

    4

    22.8

    3.85

    Hornet 4 Drive

    automatic

    1

    3

    21.4

    3.08

    Hornet Sportabout

    automatic

    2

    3

    18.7

    3.15

    Valiant

    automatic

    1

    3

    18.1

    2.76

    Finally, adjust widths and heights:

    myft <- autofit(myft)
    myft

    Some measures

    Car name

    Transmission

    # carburetors

    # forward gears

    Miles/(US) gallon

    Rear axle ratio

    Mazda RX4

    manual

    4

    4

    21.0

    3.90

    Mazda RX4 Wag

    manual

    4

    4

    21.0

    3.90

    Datsun 710

    manual

    1

    4

    22.8

    3.85

    Hornet 4 Drive

    automatic

    1

    3

    21.4

    3.08

    Hornet Sportabout

    automatic

    2

    3

    18.7

    3.15

    Valiant

    automatic

    1

    3

    18.1

    2.76

    With package officer

    The following code is producing a PowerPoint document containing the flextable.

    library(officer)
    read_pptx() %>% 
      add_slide(layout = "Title and Content", master = "Office Theme") %>% 
      ph_with_flextable(myft, type = "body") %>% 
      print(target = "../../static/files/flextable_example_01.pptx")

    Download file flextable_example_01.pptx – view with office web viewer

    The following code is producing a Word document containing the flextable.

    library(officer)
    read_docx() %>% 
      body_add_flextable(value = myft) %>% 
      print(target = "../../static/files/flextable_example_01.docx")

    Download file flextable_example_01.docx – view with office web viewer

    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.