# Subsetting Tables

#### Gabriel Becker and Adrian Waddell

#### 2022-05-20

## Introduction

`TableTree` objects are based on a tree data structure as the name indicates. The package is written such that the user does not need to walk trees for many basic table manipulations. Walking trees will still be necessary for certain manipulation and will be the subject of a different vignette.

In this vignette we show some methods to subset tables and to extract cell values.

We will use the following table for illustrative purposes:

    library(rtables)
    library(dplyr)

    tbl <- basic_table() %>%
      split_cols_by("ARM") %>%
      split_rows_by("SEX", split_fun = drop_split_levels) %>%
      analyze(c("AGE", "STRATA1")) %>%
      build_table(ex_adsl %>% filter(SEX %in% c("M", "F")))

    tbl

                A: Drug X   B: Placebo   C: Combination
    ———————————————————————————————————————————————————
    F
      AGE
        Mean      32.76       34.12          35.20
      STRATA1
        A          21           24             18
        B          25           27             21
        C          33           26             27
    M
      AGE
        Mean      35.57       37.44          35.38
      STRATA1
        A          16           19             20
        B          21           17             21
        C          14           19             19

The `[` accessor function always returns an `TableTree` object if `drop=TRUE` is not set. The first argument are the row indices and the second argument the column indices. Alternatively logical subsetting can be used. The indices are based on visible rows and not on the tree structure. So:

    tbl[1, 1]

        A: Drug X
    —————————————
    F

is a table with an empty cell because the first row is a label row. We need to access a cell with actual cell data:

    tbl[3, 1]

           A: Drug X
    ————————————————
    Mean     32.76

which is another `TableTree` and not an `rcell`. If we wanted the `rcell` we need to use the `drop` argument:

    tbl[3, 1, drop = TRUE]

    [1] 32.75949

One can access multiple rows and columns:

    tbl[1:3, 1:2]

               A: Drug X   B: Placebo
    —————————————————————————————————
    F
      AGE
        Mean     32.76       34.12

Note that we do not repeat label rows for descending children, e.g.

    tbl[2:4, ]

              A: Drug X   B: Placebo   C: Combination
    —————————————————————————————————————————————————
    AGE
      Mean      32.76       34.12          35.20
    STRATA1

does not show that the first row is derived from `AGE`. In order to repeat content/label information one should use the pagination feature. Please read the related vignette.

## Path Based Cell Value Accessing:

Cell values can also be access via path information. The functions `row_paths`, `col_paths`, `row_paths_summary`, `col_paths_summary` are helpful to get information on the paths.

    tbl2 <- basic_table() %>%
      split_cols_by("ARM") %>%
      split_cols_by("SEX", split_fun = drop_split_levels) %>%
      analyze(c("AGE", "STRATA1")) %>%
      build_table(ex_adsl %>% filter(SEX %in% c("M", "F")))

    tbl2

                A: Drug X      B: Placebo      C: Combination
                F       M       F       M        F         M
    ———————————————————————————————————————————————————————————
    AGE
      Mean    32.76   35.57   34.12   37.44    35.20     35.38
    STRATA1
      A        21      16      24      19       18        20
      B        25      21      27      17       21        21
      C        33      14      26      19       27        19

So the column paths are as follows:

    col_paths_summary(tbl2)

    label             path
    —————————————————————————————————————————————
    A: Drug X         ARM, A: Drug X
      F               ARM, A: Drug X, SEX, F
      M               ARM, A: Drug X, SEX, M
    B: Placebo        ARM, B: Placebo
      F               ARM, B: Placebo, SEX, F
      M               ARM, B: Placebo, SEX, M
    C: Combination    ARM, C: Combination
      F               ARM, C: Combination, SEX, F
      M               ARM, C: Combination, SEX, M

and the row paths are as follows:

    row_paths_summary(tbl2)

    rowname    node_class    path
    ———————————————————————————————————————————————————
    AGE        LabelRow      ma_AGE_STRATA1, AGE
      Mean     DataRow       ma_AGE_STRATA1, AGE, Mean
    STRATA1    LabelRow      ma_AGE_STRATA1, STRATA1
      A        DataRow       ma_AGE_STRATA1, STRATA1, A
      B        DataRow       ma_AGE_STRATA1, STRATA1, B
      C        DataRow       ma_AGE_STRATA1, STRATA1, C

So in order to get the average age for all female patients in arm `A: Drug X`:

    value_at(tbl2, c("AGE",  "Mean"), c("ARM", "A: Drug X", "SEX", "F"))

    [1] 32.75949

You can also request information from non-cell specific paths with the `cell_values` function:

    cell_values(tbl2, c("AGE", "Mean"), c("ARM", "A: Drug X"))

    $`A: Drug X.F`
    [1] 32.75949

    $`A: Drug X.M`
    [1] 35.56863

Note the return value of `cell_values` is always a list even if you specify a path to a cell:

    cell_values(tbl2, c("AGE",  "Mean"), c("ARM", "A: Drug X", "SEX", "F"))

    $`A: Drug X.F`
    [1] 32.75949

Hence, use `value_at` if you want to access data from a cell, and `cell_values` if you want to access data from multiple cells.