---
title: "flextable formatting"
output: 
  rmarkdown::html_vignette:
    toc: true 
    toc_depth: 3
vignette: >
  %\VignetteIndexEntry{Format flextable objects}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---

```{r echo = FALSE}
knitr::opts_chunk$set(
  message = FALSE,
  collapse = TRUE,
  comment = "#>")
```


```{r warning=FALSE, echo=FALSE, message=FALSE}
library(officer)
library(flextable)
```

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.

```{r}
myft <- flextable(head(iris))
myft
```

<div class="row">

<div class="col-12 col-sm-8 col-md-6">

### bold

```{r}
myft <- flextable(head(iris)) 
myft <- bold(myft, part = "header") # bold header
myft
```

</div>

<div class="col-12 col-sm-8 col-md-6">

### Font size

```{r}
myft <- fontsize(myft, part = "header", size = 12) 
myft
```

</div>
</div>

<div class="row">

<div class="col-12 col-sm-8 col-md-6">

### change font color

```{r}
myft <- color(myft, color = "#E4C994")
myft
```

</div>

<div class="col-12 col-sm-8 col-md-6">

### Italic

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

</div>
</div>

<div class="row">

<div class="col-12 col-sm-8 col-md-6">

### change background color

```{r}
# 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
```

</div>

<div class="col-12 col-sm-8 col-md-6">

### Text alignment

```{r}
myft <- align( myft, align = "center", part = "all" )
myft
```

</div>
</div>


<div class="row">

<div class="col-12 col-sm-8 col-md-6">

### add padding

```{r}
myft <- padding( myft, padding = 3, part = "all" )
myft
```

</div>

<div class="col-12 col-sm-8 col-md-6">

### change font

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

</div>
</div>


### Text rotation 

Text rotation is possible in flextable objects by using function `rotate()`.

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

- "lrtb", left to right top to bottom - the default value
- "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".


<div class="row">

<div class="col-12 col-sm-8 col-md-6">

```{r}
ft <- flextable(head(iris))
ft <- rotate(ft, rotation = "tbrl", align = "center", part = "header")
ft <- align(ft, align = "right", part = "header")
ft <- valign(ft, valign = "center", part = "header")
ft <- align(ft, align = "center", part = "body")
```

</div>

<div class="col-12 col-sm-8 col-md-6">

```{r echo=FALSE}
ft
```

</div>

</div>


## Borders

*Borders properties can be defined with function `border()` but the function 
requires careful settings to avoid overlapping borders.*

If no special formatting is needed, best is to use `border_outer()`, 
`border_inner_h()` and `border_inner_v()`.

```{r}
library(officer)
big_border = fp_border(color="orange", width = 2)
border_v = fp_border(color="gray")
border_h = fp_border(color="gray")

dat <- iris[c(1:2, 51:52, 101:102),]
ft <- flextable(dat)
ft <- border_remove(x = ft)
ft <- border_outer(ft, part="all", border = big_border )
ft <- border_inner_h(ft, part="all", border = border_h )
ft <- border_inner_v(ft, part="all", border = border_v )
ft
```

When more control over borders formatting is necessary, the following 
functions can be used to add vertical or horizontal lines as borders:

* `hline()`: set bottom borders (inner horizontal)
* `vline()`: set right borders (inner vertical)
* `hline_top()`: set the top border (outer horizontal)
* `hline_bottom()`: set the bottom border (outer horizontal)
* `vline_left()`: set the left border (outer vertical)
* `vline_right()`: set the right border (outer vertical)

```{r}
dat <- iris[c(1:2, 51:52, 101:102),]
ft <- flextable(dat)
ft <- border_remove( ft )

big_b <- fp_border(color="gray70", width = 3)
std_b <- fp_border(color="orange", style = "dashed")

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


## Conditional formatting

Conditional formatting can be made by using the selector arguments.

```{r warning=FALSE, message=FALSE}
dat <- iris[c(1:2, 51:52, 101:102),]
ft <- flextable(dat)
ft <- fontsize(ft, size = 14, part = "all")
ft <- color(ft, i = ~ Sepal.Length < 5 & Petal.Length > 1.3, 
        j = ~ Petal.Width + Species, 
        color="red")
ft <- italic(ft, i = ~ Sepal.Length > 5)
ft <- bold(ft, i = 4, j = "Sepal.Length")
ft
```

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

```{r warning=FALSE, message=FALSE}
row_id <- with(dat, Sepal.Length < 5 & Petal.Length > 1.3 )
col_id <- c("Petal.Width", "Species")

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

ft
```

## Function style

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

> Its 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`


```{r}
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 <- flextable(head(mtcars, n = 10 ))
ft <- style( ft, pr_c = def_cell, pr_p = def_par, pr_t = def_text, part = "all")  
ft

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

