---
title: "Pagination"
output: rmarkdown::html_vignette
vignette: >
  %\VignetteIndexEntry{Pagination}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---

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

A major piece of the advantage that **{clinify}** offers is control over pagination. Clinical tables can get fairly specific in how pagination is handled, requiring page breaks to occur in specific places, data driven content to be pulled into different portions of the table, or overflowing columns into multiple pages. **{clinify}** offers a few different function to help with this process. 

## `clin_auto_page()`

The most simple method of pagination is to let Word take the reins and do most of the work for you. Word has a feature called `keep_with_next` where you can specify groups of rows that _shouldn't_ be broken by page breaks. {flextable} implements this using the function `keep_with_next`, and in **{clinify}** we've added a simple wrapper called `clin_auto_page()`. 

`clin_auto_page()` works by taking a grouping variable, which will be pulled out of the table, and using that to determine the appropriate `keep_with_next` groupings. Note that when using this function, you're not specifying a variable to _insert_ page breaks, but rather saying "do not split rows within this group across pages". It's also important to note that the effect of this function won't be apparent when printing to the screen, and only within a word document itself. `keep_with_next` is a feature of Word, so in an HTML view there's nothing much to see.

```{r}
library(clinify)
clintable(mtcars) |>
  clin_auto_page("gear")
```

 If you can accomplish what you need using this function, we recommend it because it takes the least effort on behalf of the programmer. The other functions that `clinify` has to offer give you more specific control, but rely more on the inputs that you provide.

 `clin_auto_page()` can use two different triggers using the `when` argument to determine the break points within paging:
  
  - `"change"`: When the value of the the `group_var` changes, a page break may be inserted, and
  - `"notempty"`: When the value of `group_var` is populated (i.e. not `NA` or `""`), a page break may be inserted.

The `when` argument is a common interface available within `clin_group_by()` and `clin_pad_by()` as well. 

Additionally, `clin_auto_page()` has the `drop` argument to specify whether the paging variable should be dropped from the table.

```{r, eval=FALSE}
clintable(mtcars) |>
  clin_auto_page("gear", when = 'notempty', drop = TRUE)
```

## `clin_page_by()`

One method of pagination for clinical tables that's been used for a long time is to pre-program a variable that specifies where page breaks should occur. When default page break methods don't suffice, this can be one way that you ensure breaks happen in the appropriate places. The `clin_page_by()` function allows you to target a variable in the table that will be used to drive this. 

Let's prep some data and provide an example.

```{r setup}
dat <- mtcars
dat["page"] <- c(
  rep(1, 10),
  rep(2, 10),
  rep(3, 10),
  c(4, 4)
)
dat2 <- rbind(dat, dat)
dat2["groups1"] <- c(
  rep("a", 32),
  rep("b", 32)
)
dat2["groups2"] <- c(
  rep("1", 16),
  rep("2", 16),
  rep("1", 16),
  rep("2", 16)
)
dat2["captions"] <- c(
  rep("Caption 1", 16),
  rep("Caption 2", 16),
  rep("Caption 3", 16),
  rep("Caption 4", 16)
)

clintable(dat2) |>
  clin_page_by("page")
```

An alternative to using a paging variable, another shortcut option is to specify the maximum rows you want to print to a specific page.

```{r}
clintable(dat2) |>
  clin_page_by(max_rows = 5)
```

## `clin_group_by()`

Another specific form of available is the function `clin_group_by()`. This function takes two arguments after the `clintable`:

- `group_by`, and
- `caption_by`

The data within variables provided in `group_by` will be extracted to lines that are printed **above** the header and in the table body. Similarly, the `caption_by` data will be pulled into footnotes attached below the table body but above the footer. 

```{r}
clintable(dat2) |>
  clin_page_by("page") |>
  clin_group_by(c("groups1", "groups2"), caption_by = "captions")
```

`clin_group_by()` can be used in combination with `clin_page_by()`, but this is not required. When these two functions are used together, page breaks will occur when **any of** the group, caption, or page variables change. 

Much the same as `clin_auto_page()`, the `clin_group_by()` function can identify groups using the `when` argument. In the `clin_group_by()`, using `when = "notempty"` will mark a group whenever any of the `group_by` variables or the `caption_by` variables are populated. When using `when = "change"` groups are marked whenever any of those variables change.

## `clin_alt_pages()`

The most complex pagination method is `clin_alt_pages()`. This function allows you to split one table across multiple pages. This is specifically reserved for circumstances in which you have a table that has too many columns to fit on one page. For example, a study may have many different treatment groups that need to be presented, or perhaps a listing needs to present a large number of columns. This isn't an ideal case for a table, but it's still a common situation. 

`clin_alt_pages()` takes two parameters after the `clintable`:

- `key_cols`: Columns frozen to each page
- `col_groups`: The sets of columns differing from page to page

```{r}
clintable(dat2) |>
  clin_page_by("page") |>
  clin_alt_pages(
    key_cols = c("mpg", "cyl", "hp"),
    col_groups = list(
      c("disp", "drat", "wt"),
      c("qsec", "vs", "am"),
      c("gear", "carb")
    )
  )
```

One thing to note about this function is that it should be paired with `clin_page_by()`. This function works by chunking the input clintable into individual pages and separating those pages using page breaks - so the number of rows printed to each page is necessary for the page splits to work effectively. If `clin_page_by()` is not provided, a warning will appear and the table will default to 20 rows per page.

As another option for creating a data driven paging variable, we've added the helper function `make_grouped_pagenums()`. This function could be helpful when creating tables using alternating pages that also using `clin_group_by()` for header labels. Alternating page tables require manual management of paging variables, since each page is technically a new table within the word document. `make_grouped_pagenums()` allows you to use a group variable and then generate a page variable that will appropriately change when the group changes. Consider this example:

```{r}
library(dplyr)
head(ToothGrowth, 20) |>
  mutate(page = make_grouped_pagenums(dose, 7))
```

Note in the output that the `page` variable either every 7 rows, or when the value of `dose` changes.