# Format flextable objects

A flextable is made of parts, an header, a body and a footer. To specify which part formatting instructions should affect, use argument `part`. Possible values are:

- “header”: the header part of the table
- “footer”: the footer part of the table
- “body”: the body part of the table
- “all”: the body and the header parts of the table

## Shortcuts functions

There are simple functions to modify formatting properties of flextable objects: `bg`, `bold`, `border`, `color`, `padding`, `fontsize`, `italic`, `align`, …

They are illustrated in the examples below.

    myft <- regulartable(head(iris))
    myft

Sepal.Length | Sepal.Width | Petal.Length | Petal.Width | Species
5.100 | 3.500 | 1.400 | 0.200 | setosa
4.900 | 3.000 | 1.400 | 0.200 | setosa
4.700 | 3.200 | 1.300 | 0.200 | setosa
4.600 | 3.100 | 1.500 | 0.200 | setosa
5.000 | 3.600 | 1.400 | 0.200 | setosa
5.400 | 3.900 | 1.700 | 0.400 | setosa

### bold

    myft <- regulartable(head(iris))
    myft <- bold(myft, part = "header") # bold header
    myft

Sepal.Length | Sepal.Width | Petal.Length | Petal.Width | Species
5.100 | 3.500 | 1.400 | 0.200 | setosa
4.900 | 3.000 | 1.400 | 0.200 | setosa
4.700 | 3.200 | 1.300 | 0.200 | setosa
4.600 | 3.100 | 1.500 | 0.200 | setosa
5.000 | 3.600 | 1.400 | 0.200 | setosa
5.400 | 3.900 | 1.700 | 0.400 | setosa

### Font size

    myft <- fontsize(myft, part = "header", size = 12)
    myft

Sepal.Length | Sepal.Width | Petal.Length | Petal.Width | Species
5.100 | 3.500 | 1.400 | 0.200 | setosa
4.900 | 3.000 | 1.400 | 0.200 | setosa
4.700 | 3.200 | 1.300 | 0.200 | setosa
4.600 | 3.100 | 1.500 | 0.200 | setosa
5.000 | 3.600 | 1.400 | 0.200 | setosa
5.400 | 3.900 | 1.700 | 0.400 | setosa

### change font color

    myft <- color(myft, color = "#E4C994")
    myft

Sepal.Length | Sepal.Width | Petal.Length | Petal.Width | Species
5.100 | 3.500 | 1.400 | 0.200 | setosa
4.900 | 3.000 | 1.400 | 0.200 | setosa
4.700 | 3.200 | 1.300 | 0.200 | setosa
4.600 | 3.100 | 1.500 | 0.200 | setosa
5.000 | 3.600 | 1.400 | 0.200 | setosa
5.400 | 3.900 | 1.700 | 0.400 | setosa

### Italic

    myft <- italic(myft, i = ~ Sepal.Length > 5,
             j = ~ Sepal.Length + Sepal.Width, italic = TRUE)
    myft

Sepal.Length | Sepal.Width | Petal.Length | Petal.Width | Species
5.100 | 3.500 | 1.400 | 0.200 | setosa
4.900 | 3.000 | 1.400 | 0.200 | setosa
4.700 | 3.200 | 1.300 | 0.200 | setosa
4.600 | 3.100 | 1.500 | 0.200 | setosa
5.000 | 3.600 | 1.400 | 0.200 | setosa
5.400 | 3.900 | 1.700 | 0.400 | setosa

### change background color

    # light gray as background color for header
    myft <-  bg(myft, bg = "#E4C994", part = "header")
    # dark gray as background color for body
    myft <-  bg(myft, bg = "#333333", part = "body")
    myft

Sepal.Length | Sepal.Width | Petal.Length | Petal.Width | Species
5.100 | 3.500 | 1.400 | 0.200 | setosa
4.900 | 3.000 | 1.400 | 0.200 | setosa
4.700 | 3.200 | 1.300 | 0.200 | setosa
4.600 | 3.100 | 1.500 | 0.200 | setosa
5.000 | 3.600 | 1.400 | 0.200 | setosa
5.400 | 3.900 | 1.700 | 0.400 | setosa

### Text alignment

    myft <- align( myft, align = "center", part = "all" )
    myft

Sepal.Length | Sepal.Width | Petal.Length | Petal.Width | Species
5.100 | 3.500 | 1.400 | 0.200 | setosa
4.900 | 3.000 | 1.400 | 0.200 | setosa
4.700 | 3.200 | 1.300 | 0.200 | setosa
4.600 | 3.100 | 1.500 | 0.200 | setosa
5.000 | 3.600 | 1.400 | 0.200 | setosa
5.400 | 3.900 | 1.700 | 0.400 | setosa

### add padding

    myft <- padding( myft, padding = 3, part = "all" )
    myft

Sepal.Length | Sepal.Width | Petal.Length | Petal.Width | Species
5.100 | 3.500 | 1.400 | 0.200 | setosa
4.900 | 3.000 | 1.400 | 0.200 | setosa
4.700 | 3.200 | 1.300 | 0.200 | setosa
4.600 | 3.100 | 1.500 | 0.200 | setosa
5.000 | 3.600 | 1.400 | 0.200 | setosa
5.400 | 3.900 | 1.700 | 0.400 | setosa

### change font

    myft <- font(myft, j = "Species", fontname = "Times")
    myft <- fontsize(myft, j = "Species", size = 14)
    myft

Sepal.Length | Sepal.Width | Petal.Length | Petal.Width | Species
5.100 | 3.500 | 1.400 | 0.200 | setosa
4.900 | 3.000 | 1.400 | 0.200 | setosa
4.700 | 3.200 | 1.300 | 0.200 | setosa
4.600 | 3.100 | 1.500 | 0.200 | setosa
5.000 | 3.600 | 1.400 | 0.200 | setosa
5.400 | 3.900 | 1.700 | 0.400 | setosa

### Text rotation

Text rotation is possible in flextable objects but will only work correctly with Word and PowerPoint outputs (html output is not always correct). This is achieved by using function `rotate()`.

Argument `rotation` is mandatory and expects one of these values:

- “lrtb”, left to right top to bottom
- “tbrl”, top to bottom right to left
- “btlr”, bottom to top left to right

Argument `align` is used for cell content vertical alignment, it should be one of these values: “top”, “bottom” or “center”.

    ft <- regulartable(head(iris))
    ft <- rotate(ft, rotation = "tbrl", align = "top", part = "header")
    ft <- theme_vanilla(ft)
    ft <- autofit(ft)

    # as autofit do not handle rotation, you will have
    # to change manually header cells'height.
    ft <- height(ft, height = 1, part = "header")
    ft

Sepal.Length | Sepal.Width | Petal.Length | Petal.Width | Species
5.100 | 3.500 | 1.400 | 0.200 | setosa
4.900 | 3.000 | 1.400 | 0.200 | setosa
4.700 | 3.200 | 1.300 | 0.200 | setosa
4.600 | 3.100 | 1.500 | 0.200 | setosa
5.000 | 3.600 | 1.400 | 0.200 | setosa
5.400 | 3.900 | 1.700 | 0.400 | setosa

## Borders

Borders properties can be defined with functions:

- `hline()`: set bottom borders of one or all parts of a flextable.
- `hline_top()`: set top border of one or all parts of a flextable.
- `hline_bottom()`: set bottom border of one or all parts of a flextable.
- `vline()`: set right borders of one or all parts of a flextable.
- `vline_left()`: set left border of one or all parts of a flextable.
- `vline_right()`: set right border of one or all parts of a flextable.

    # remove all defined borders
    myft <- border_remove( myft )

    big_b <- fp_border(color="gray70", width = 2)
    std_b <- fp_border(color="white")

    myft <- vline( myft, border = std_b, part = "all" )
    myft <- vline_left( myft, border = big_b, part = "all" )
    myft <- vline_right( myft, border = big_b, part = "all" )
    myft <- hline( myft, border = std_b )
    myft <- hline_bottom( myft, border = big_b )
    myft <- hline_top( myft, border = big_b, part = "all" )
    myft

Sepal.Length | Sepal.Width | Petal.Length | Petal.Width | Species
5.100 | 3.500 | 1.400 | 0.200 | setosa
4.900 | 3.000 | 1.400 | 0.200 | setosa
4.700 | 3.200 | 1.300 | 0.200 | setosa
4.600 | 3.100 | 1.500 | 0.200 | setosa
5.000 | 3.600 | 1.400 | 0.200 | setosa
5.400 | 3.900 | 1.700 | 0.400 | setosa

Or when borders design is simple with:

- `border_outer()`: apply a border to outer cells of one or all parts of a flextable.
- `border_inner()`: apply a border to inner cells of one or all parts of a flextable.

    std_b2 <- fp_border(color="white", style = "dashed")

    # remove all defined borders
    myft <- border_remove( myft )

    myft <- border_outer( myft, border = big_b, part = "all" )
    myft <- border_inner_h( myft, border = std_b, part = "all" )
    myft <- border_inner_v( myft, border = std_b2, part = "all" )
    myft

Sepal.Length | Sepal.Width | Petal.Length | Petal.Width | Species
5.100 | 3.500 | 1.400 | 0.200 | setosa
4.900 | 3.000 | 1.400 | 0.200 | setosa
4.700 | 3.200 | 1.300 | 0.200 | setosa
4.600 | 3.100 | 1.500 | 0.200 | setosa
5.000 | 3.600 | 1.400 | 0.200 | setosa
5.400 | 3.900 | 1.700 | 0.400 | setosa

## Conditional formatting

Conditional formatting can be made by using the selector arguments.

    myft <- color(myft, i = ~ Sepal.Length < 5 & Petal.Length > 1.3,
            j = ~ Petal.Width + Species,
            color="red")
    myft <- bg(myft, j = 1, bg = "#D3C994", part = "header")
    myft <- italic(myft, i = ~ Sepal.Length > 5)
    myft <- bold(myft, i = 4, j = "Sepal.Length")
    myft

Sepal.Length | Sepal.Width | Petal.Length | Petal.Width | Species
5.100 | 3.500 | 1.400 | 0.200 | setosa
4.900 | 3.000 | 1.400 | 0.200 | setosa
4.700 | 3.200 | 1.300 | 0.200 | setosa
4.600 | 3.100 | 1.500 | 0.200 | setosa
5.000 | 3.600 | 1.400 | 0.200 | setosa
5.400 | 3.900 | 1.700 | 0.400 | setosa

`i` and `j` arguments can be also standard R vectors:

    row_id <- with(head(iris), Sepal.Length < 5 & Petal.Length > 1.3 )
    col_id <- c("Petal.Width", "Species")

    myft <- color(myft, i = row_id, j = col_id, color="red")

    myft

Sepal.Length | Sepal.Width | Petal.Length | Petal.Width | Species
5.100 | 3.500 | 1.400 | 0.200 | setosa
4.900 | 3.000 | 1.400 | 0.200 | setosa
4.700 | 3.200 | 1.300 | 0.200 | setosa
4.600 | 3.100 | 1.500 | 0.200 | setosa
5.000 | 3.600 | 1.400 | 0.200 | setosa
5.400 | 3.900 | 1.700 | 0.400 | setosa

## Function style

The `style` function lets you style a selection of the flextable with several formatting properties.

> It main advantage is to let specify a set of formatting properties for a selection.

Package officer needs to be loaded, it provides the following formatting properties:

- for text: `fp_text`
- for paragraphs: `fp_par`
- for cells: `fp_cell` and `fp_border`

    library(officer)
    def_cell <- fp_cell(border = fp_border(color="#00C9C9"))
    def_par <- fp_par(text.align = "center")
    def_text <- fp_text(color="#999999", italic = TRUE)
    def_text_header <- update(color="black", def_text, bold = TRUE)

    ft <- regulartable(head(mtcars, n = 10 ))
    ft <- style( ft, pr_c = def_cell, pr_p = def_par, pr_t = def_text, part = "all")
    ft

mpg | cyl | disp | hp | drat | wt | qsec | vs | am | gear | carb
21.000 | 6.000 | 160.000 | 110.000 | 3.900 | 2.620 | 16.460 | 0.000 | 1.000 | 4.000 | 4.000
21.000 | 6.000 | 160.000 | 110.000 | 3.900 | 2.875 | 17.020 | 0.000 | 1.000 | 4.000 | 4.000
22.800 | 4.000 | 108.000 | 93.000 | 3.850 | 2.320 | 18.610 | 1.000 | 1.000 | 4.000 | 1.000
21.400 | 6.000 | 258.000 | 110.000 | 3.080 | 3.215 | 19.440 | 1.000 | 0.000 | 3.000 | 1.000
18.700 | 8.000 | 360.000 | 175.000 | 3.150 | 3.440 | 17.020 | 0.000 | 0.000 | 3.000 | 2.000
18.100 | 6.000 | 225.000 | 105.000 | 2.760 | 3.460 | 20.220 | 1.000 | 0.000 | 3.000 | 1.000
14.300 | 8.000 | 360.000 | 245.000 | 3.210 | 3.570 | 15.840 | 0.000 | 0.000 | 3.000 | 4.000
24.400 | 4.000 | 146.700 | 62.000 | 3.690 | 3.190 | 20.000 | 1.000 | 0.000 | 4.000 | 2.000
22.800 | 4.000 | 140.800 | 95.000 | 3.920 | 3.150 | 22.900 | 1.000 | 0.000 | 4.000 | 2.000
19.200 | 6.000 | 167.600 | 123.000 | 3.920 | 3.440 | 18.300 | 1.000 | 0.000 | 4.000 | 4.000

    ft <- style( ft, pr_t = def_text_header, part = "header")
    ft

mpg | cyl | disp | hp | drat | wt | qsec | vs | am | gear | carb
21.000 | 6.000 | 160.000 | 110.000 | 3.900 | 2.620 | 16.460 | 0.000 | 1.000 | 4.000 | 4.000
21.000 | 6.000 | 160.000 | 110.000 | 3.900 | 2.875 | 17.020 | 0.000 | 1.000 | 4.000 | 4.000
22.800 | 4.000 | 108.000 | 93.000 | 3.850 | 2.320 | 18.610 | 1.000 | 1.000 | 4.000 | 1.000
21.400 | 6.000 | 258.000 | 110.000 | 3.080 | 3.215 | 19.440 | 1.000 | 0.000 | 3.000 | 1.000
18.700 | 8.000 | 360.000 | 175.000 | 3.150 | 3.440 | 17.020 | 0.000 | 0.000 | 3.000 | 2.000
18.100 | 6.000 | 225.000 | 105.000 | 2.760 | 3.460 | 20.220 | 1.000 | 0.000 | 3.000 | 1.000
14.300 | 8.000 | 360.000 | 245.000 | 3.210 | 3.570 | 15.840 | 0.000 | 0.000 | 3.000 | 4.000
24.400 | 4.000 | 146.700 | 62.000 | 3.690 | 3.190 | 20.000 | 1.000 | 0.000 | 4.000 | 2.000
22.800 | 4.000 | 140.800 | 95.000 | 3.920 | 3.150 | 22.900 | 1.000 | 0.000 | 4.000 | 2.000
19.200 | 6.000 | 167.600 | 123.000 | 3.920 | 3.440 | 18.300 | 1.000 | 0.000 | 4.000 | 4.000

## set_formatter function

When working with `regulartable`, it is possible to define the functions that will be used to format the data.frame values into strings. `set_formatter` set column formatter functions.

> Note `set_formatter` only works with `regulartable` objects, use `display` for `flextable` objects.

    ft <- regulartable(head(mtcars, n = 10 ),
                       col_keys = c("gear", "mpg", "qsec"))
    ft <- set_formatter(ft,
        mpg = function(x) sprintf("%.04f", x),
        gear = function(x) sprintf("%.0f gears", x)
      )
    ft <- theme_booktabs(ft)
    ft <- autofit(ft)
    ft

gear | mpg | qsec
4 gears | 21.0000 | 16.460
4 gears | 21.0000 | 17.020
4 gears | 22.8000 | 18.610
3 gears | 21.4000 | 19.440
3 gears | 18.7000 | 17.020
3 gears | 18.1000 | 20.220
3 gears | 14.3000 | 15.840
4 gears | 24.4000 | 20.000
4 gears | 22.8000 | 22.900
4 gears | 19.2000 | 18.300

## display function

`flextable` content is defined with `display` function.

> Note `display` only works with `flextable` objects, use `set_formatter` for `regulartable` objects.

Below the starting point of next illustrations:

    myft <- flextable( head(mtcars),
      col_keys = c("am", "separator", "gear", "mpg", "drat", "qsec" ))
    myft <- bold(myft, part = "header")
    myft <- border(myft, border = fp_border( width = 0),
      border.top = fp_border(), border.bottom = fp_border(),
      part = "all")
    myft <- align(myft, align = "right", part = "all" )
    myft <- border(myft, j = ~ separator, border = fp_border(width=0), part = "all")
    myft <- width(myft, j = ~ separator, width = .1)
    myft

am |  | gear | mpg | drat | qsec
1.000 |  | 4.000 | 21.000 | 3.900 | 16.460
1.000 |  | 4.000 | 21.000 | 3.900 | 17.020
1.000 |  | 4.000 | 22.800 | 3.850 | 18.610
0.000 |  | 3.000 | 21.400 | 3.080 | 19.440
0.000 |  | 3.000 | 18.700 | 3.150 | 17.020
0.000 |  | 3.000 | 18.100 | 2.760 | 20.220

The function requires argument `pattern` which is a string template inspired by mustaches. The string will be expanded with tags using values provided in `formatters` argument; tags can eventually be formatted with `fprops` argument.

The following example shows how to control the format of displayed values and how to associate them with specific text formatting properties (bold red text):

    myft <- display( myft, col_key = "mpg", pattern = "{{mpg}}",
        formatters = list(mpg ~ sprintf("%.01f", mpg) ),
        fprops = list(mpg = fp_text(color = "red", italic = TRUE) )
      )

    myft

am |  | gear | mpg | drat | qsec
1.000 |  | 4.000 | 21.0 | 3.900 | 16.460
1.000 |  | 4.000 | 21.0 | 3.900 | 17.020
1.000 |  | 4.000 | 22.8 | 3.850 | 18.610
0.000 |  | 3.000 | 21.4 | 3.080 | 19.440
0.000 |  | 3.000 | 18.7 | 3.150 | 17.020
0.000 |  | 3.000 | 18.1 | 2.760 | 20.220

With that system, it’s easy to concatenate multiple values:

    myft <- display( myft, i = ~ drat > 3.6,
               col_key = "mpg", pattern = "{{mpg}} with {{carb}}",
               formatters = list(mpg ~ sprintf("%.01f", mpg),
                                 carb ~ sprintf("# %.0f carb.", carb) ),
                  fprops = list(mpg = fp_text(color = "#CC55CC", bold = TRUE) )
      )
    myft <- autofit(myft)
    myft

am |  | gear | mpg | drat | qsec
1.000 |  | 4.000 | 21.0 with # 4 carb. | 3.900 | 16.460
1.000 |  | 4.000 | 21.0 with # 4 carb. | 3.900 | 17.020
1.000 |  | 4.000 | 22.8 with # 1 carb. | 3.850 | 18.610
0.000 |  | 3.000 | 21.4 | 3.080 | 19.440
0.000 |  | 3.000 | 18.7 | 3.150 | 17.020
0.000 |  | 3.000 | 18.1 | 2.760 | 20.220

Or to define specific title headers:

    myft <- display( myft, col_key = "mpg",
       part = "header",
       pattern = "Miles/(US) gallon {{my_message}}",
       formatters = list(
         my_message ~ sprintf("* with num of carb.")
         ),
       fprops = list(
         my_message = fp_text(color = "gray", vertical.align = "superscript")
         )
       )
    myft <- autofit(myft)
    myft

am |  | gear | Miles/(US) gallon * with num of carb. | drat | qsec
1.000 |  | 4.000 | 21.0 with # 4 carb. | 3.900 | 16.460
1.000 |  | 4.000 | 21.0 with # 4 carb. | 3.900 | 17.020
1.000 |  | 4.000 | 22.8 with # 1 carb. | 3.850 | 18.610
0.000 |  | 3.000 | 21.4 | 3.080 | 19.440
0.000 |  | 3.000 | 18.7 | 3.150 | 17.020
0.000 |  | 3.000 | 18.1 | 2.760 | 20.220

### Images

Function `display` supports images insertion. Use function `as_image` within `formatters` argument.

    img.file <- file.path( R.home("doc"), "html", "logo.jpg" )

    myft <- display( myft, i = ~ qsec > 18, col_key = "qsec",
               pattern = "blah blah {{r_logo}} {{qsec}}",
               formatters = list(
                 r_logo ~ as_image(qsec, src = img.file, width = .20, height = .15),
                 qsec ~ sprintf("qsec: %.1f", qsec) ),
               fprops = list(qsec = fp_text(color = "orange", vertical.align = "superscript"))
               )
    myft <- autofit(myft)
    myft

am |  | gear | Miles/(US) gallon * with num of carb. | drat | qsec
1.000 |  | 4.000 | 21.0 with # 4 carb. | 3.900 | 16.460
1.000 |  | 4.000 | 21.0 with # 4 carb. | 3.900 | 17.020
1.000 |  | 4.000 | 22.8 with # 1 carb. | 3.850 | blah blah qsec: 18.6
0.000 |  | 3.000 | 21.4 | 3.080 | blah blah qsec: 19.4
0.000 |  | 3.000 | 18.7 | 3.150 | 17.020
0.000 |  | 3.000 | 18.1 | 2.760 | blah blah qsec: 20.2