---
title: "Comparison with dplyr Tabulation"
author: "Gabriel Becker and Adrian Waddell"
date: "`r Sys.Date()`"
output: rmarkdown::html_vignette
vignette: >
  %\VignetteIndexEntry{Comparison with dplyr Tabulation}
  %\VignetteEncoding{UTF-8}
  %\VignetteEngine{knitr::rmarkdown}
editor_options: 
  chunk_output_type: console
---



```{r, echo=FALSE}
knitr::opts_chunk$set(comment = "")
```

```{css, echo=FALSE}
.reveal .r code {
    white-space: pre;
}
```

## Introduction

In this vignette we would like to discuss the similarities and differences between `dplyr` and `rtable`.

Much of the `rtables` framework focuses on tabulation/summarizing of data and then the visualization of the table. In this vignette we focus on summarizing data using `dplyr` and contrast it to `rtables`. We won't pay attention to the table visualizaion/markup and just derive the cell content.

Using `dplyr` to summarize data and `gt` to visualize the table is a good way if the tabulation is of a certain nature or complexity. However, there are tables such as the table created in the `introduction` vignette that take some effort to create with `dplyr`. Part of the effort is due to fact that when using dplyr the table data is stored in `data.frame`s or `tibble`s which is not the most natural way to represent a table as we will show in this vignette.

If you know a more elegant way of deriving the table content with `dplyr` please let us know and we will update the vignette.


```{r, message=FALSE}
library(rtables)
library(dplyr)
```

Here is table and data used in the `introduction` vignette:

```{r}
n <- 400

set.seed(1)

df <- tibble(
  arm = factor(sample(c("Arm A", "Arm B"), n, replace = TRUE), levels = c("Arm A", "Arm B")),
  country = factor(sample(c("CAN", "USA"), n, replace = TRUE, prob = c(.55, .45)), levels = c("CAN", "USA")),
  gender = factor(sample(c("Female", "Male"), n, replace = TRUE), levels = c("Female", "Male")),
  handed = factor(sample(c("Left", "Right"), n, prob = c(.6, .4), replace = TRUE), levels = c("Left", "Right")),
  age = rchisq(n, 30) + 10
) %>% mutate(
  weight = 35 * rnorm(n, sd = .5) + ifelse(gender == "Female", 140, 180)
) 

basic_table() %>%
  split_cols_by("arm") %>%
  split_cols_by("gender") %>%
  add_colcounts() %>%
  split_rows_by("country") %>%
  summarize_row_groups() %>%
  split_rows_by("handed") %>%
  summarize_row_groups() %>%
  analyze("age", afun = mean, format = "xx.x") %>%
  build_table(df)
```


## Getting Started

We will start by deriving the first data cell on row 3 (note, row 1 and 2 have content cells, see the `introduction` vignette). Cell 3,1 contains the mean age for left handed & female Canadians in "Arm A":


```{r}
mean(df$age[df$country == "CAN" & df$arm == "Arm A" & df$gender == "Female" & df$handed == "Left"])
```

or with `dplyr`:

```{r}
df %>%
  filter(country == "CAN", arm == "Arm A", gender == "Female", handed == "Left") %>%
  summarise(mean_age = mean(age))
```

Further, `dplyr` gives us other verbs to easily get the average age of left handed Canadians for each group defined by the 4 columns:

```{r}
df %>%
  group_by(arm, gender) %>%
  filter(country == "CAN", handed == "Left") %>%
  summarise(mean_age = mean(age))
```

We can further get to all the average age cell values with:

```{r}
average_age <- df %>%
  group_by(arm, gender, country, handed) %>%
  summarise(mean_age = mean(age))

average_age
```

In `rtable` syntax we need the following code to get to the same content:

```{r}
basic_table() %>%
  split_cols_by("arm") %>%
  split_cols_by("gender") %>%
  split_rows_by("country") %>%
  split_rows_by("handed") %>%
  analyze("age", afun = mean, format = "xx.x") %>%
  build_table(df)
```

As mentioned in the introduction to this vignette, please ignore the difference in arranging and formatting the data: it's possible to condense the `rtable` more and it is possible to make the tibble look more like the reference table using the `gt` R package. 

In terms of tabulation for this example there was arguably not much added by `rtables` over `dplyr`.

## Content Information

We will now focus on the count percentage information for handedness for each country. For that we need to get the correct denominator for the percentages 



```{r}
df %>% 
  group_by(arm, gender, country, handed) %>%
  summarize(mean = mean(age), c_h_count = n()) %>%
  # now the `handed` grouping has been removed, therefore we can calculate percent now:
  mutate(c_h_percent = c_h_count / sum(c_h_count))
```

which has 16 rows (cells) like the `average_age` data frame defined above. Next, we will derive the group information for countries:

```{r}
df %>% 
  group_by(arm, gender, country, handed) %>%
  summarize(mean = mean(age), c_h_count = n()) %>%
  mutate(c_h_percent = c_h_count / sum(c_h_count)) %>%
  mutate(c_count = sum(c_h_count)) %>%
  ungroup(country) %>%
  # note that we always use the finest level of counts to avoid duplicate counting
  mutate(c_percent = c_count / sum(c_h_count))
```

Note that the information in `c_count` and `c_percent` must be repeated, as there are only 8 country group summaries but the rest of the data structure requires 16 rows for the information.

The `rtables` call in contrast is:

```{r}
basic_table() %>%
  split_cols_by("arm") %>%
  split_cols_by("gender") %>%
  add_colcounts() %>%
  split_rows_by("country") %>%
  summarize_row_groups() %>%
  split_rows_by("handed") %>%
  summarize_row_groups() %>%
  analyze("age", afun = mean, format = "xx.x") %>%
  build_table(df)
```

Further, the `rtable` syntax has hopefully also become a bit more straightforward to derive the cell values than with `dplyr` for this particular table.


## Summary

In this vignette learned that:

* many tables are quite easily created with `dplyr` and `data.frame` or `tibble` as data structure
  * `dplyr` keeps simple things simple
* if tables have group summaries then repeating of information is required
* `rtables` streamlines the construction of complex tables

We recommend that you continue reading the `clinical_trials` vignette where we create a number of more advanced tables using layouts.
