Skip to contents

Takes a large table, common rows, and header information and constructs a table that is a subset of those components using supplied ranges of rows and columns.

Usage

build_span(
  table_body = NULL,
  row_common = NULL,
  table_body_head = NULL,
  row_common_head = NULL,
  header_format = "text",
  obnd = NULL,
  row_sel = NULL,
  col_sel = NULL,
  table_alignment = "center",
  inner_border = officer::fp_border(color = "black", width = 0.3),
  outer_border = officer::fp_border(color = "black", width = 2),
  set_header_inner_border_v = TRUE,
  set_header_inner_border_h = TRUE,
  set_header_outer_border = TRUE,
  set_body_inner_border_v = TRUE,
  set_body_inner_border_h = FALSE,
  set_body_outer_border = TRUE,
  notes_detect = NULL
)

Arguments

table_body

Data frame with the body of the large table.

row_common

Data frame with the common rows.

table_body_head

Data frame or matrix with headers for the table body.

row_common_head

Data frame or matrix with headers for the common rows.

header_format

Format of the header either "text" (default) or "md" for markdown.

obnd

Optional onbrand object used to format markdown. The default NULL value will use default formatting.

row_sel

Indices of rows to build to the table with.

col_sel

Indices of columns to build to the table with.

table_alignment

Character string specifying the alignment #'of the table (body and headers). Can be "center" (default), "left", "right", or "justify"

inner_border

Border object for inner border lines defined using officer::fp_border()

outer_border

Border object for outer border lines defined using officer::fp_border()

set_header_inner_border_v

Boolean value to enable or disable inner vertical borders for headers

set_header_inner_border_h

Boolean value to enable or disable inner horizontal borders for headers

set_header_outer_border

Boolean value to enable or disable outer border for headers

set_body_inner_border_v

Boolean value to enable or disable inner vertical borders for the body

set_body_inner_border_h

Boolean value to enable or disable inner horizontal borders for the body

set_body_outer_border

Boolean value to enable or disable outer border borders for the body

notes_detect

Vector of strings to detect in output tables (example c("NC", "BLQ")).

Value

list with the following elements

  • df: Data frame with the built table.

  • ft: The data frame as a flextable object.

  • notes: Note placeholders found in the table.

Details

The way the data frames relate to each other are mapped out below. The dimensions of the different data frames are identified below (nrow x ncol)

#                            col_sel
#                      |<--------------->|
#
#|--------------------------------------------| ---
#|                 |   .                 .    |  ^
#|                 |   .                 .    |  |
#| row_common_head |   . table_body_head .    |  | m
#|      m x n      |   .      m x c      .    |  |
#|                 |   .                 .    |  v
#|--------------------------------------------| ---
#|                 |   .                 .    |  ^
#|                 |   .                 .    |  |
#|    row_common   |   .   table_body    .    |  |
#|      r x n      |   .     r x c       .    |  |
#|                 |   .                 .    |  |
#|.................|..........................|  |     -
#|                 |   ./  /  /  /  /  / .    |  |     ^
#|                 |   .  /  /  /  /  /  .    |  | r   |
#|                 |   . /  /  /  /  /  /.    |  |     | row_sel
#|                 |   ./  /  /  /  /  / .    |  |     |
#|                 |   .  /  /  /  /  /  .    |  |     v
#|.................|...../../../../../../.... |  |     -
#|                 |   .                 .    |  |
#|                 |   .                 .    |  v
#|--------------------------------------------| ---
#
#|<--------------->|<------------------------>|
#        n                    c

Examples

library(formods)
library(readxl)
library(dplyr)
#> 
#> Attaching package: ‘dplyr’
#> The following objects are masked from ‘package:stats’:
#> 
#>     filter, lag
#> The following objects are masked from ‘package:base’:
#> 
#>     intersect, setdiff, setequal, union
library(tidyr)

# First we need to create some data. 
# This will read in a test dataset:
DS = readxl::read_excel(
 path  = system.file(package="formods", 
                     "test_data", 
                     "TEST_DATA.xlsx"),
 sheet = "DATA")

# This will filter the dataset down and modify the formatting
DS = dplyr::filter(DS, EVID == 0)                          |>
  dplyr::filter(ID <= 30)                                  |>
  dplyr::select(ID, TIME, DV, CMT)                         |>
  dplyr::mutate(CMT  = ifelse(.data[["CMT"]] == "C_ng_ml", 
                             "Test Article", 
                             .data[["CMT"]]))              |>
  dplyr::select(ID, TIME, DV, CMT)                         |>
  dplyr::mutate(CMT = ifelse(.data[["CMT"]] == "BM_ng_ml", 
                            "Biomarker", 
                            .data[["CMT"]]))               |>
  dplyr::rename(Analyte = "CMT")                           |>
  dplyr::mutate(DV = ifelse(.data[["DV"]] == 0, "BQL", .data[["DV"]]))

# This represents the large table we want to split up into smaller tables 
wide_df = tidyr::pivot_wider(DS,
  values_from = "DV",
  names_from  = "ID")               |>
  dplyr::arrange(Analyte, TIME)     |>
  dplyr::mutate(TIME = as.character(.data[["TIME"]]))    

# The first two columns represent the rows
# that are common across the tables:
row_common = wide_df[,1:2]

# The remaining columns represent the body of the table:
table_body = wide_df[,3:ncol(wide_df)]

# Next we create matrices that contain the header 
# information for each component above:
row_common_head = matrix(
  data  = c("Time", "Analyte",
            "(hr)", "(ng/ml)"),
  ncol  = 2,
  byrow = TRUE)

table_body_head = matrix(
  data  = c(rep("Subject ID", times=ncol(table_body)), 
            names(table_body)),
  ncol  = ncol(table_body),
  byrow = TRUE)


# This builds all of the tables:
span_res = span_table(table_body      = table_body,
                      row_common      = row_common,
                      table_body_head = table_body_head,
                      row_common_head = row_common_head,
                      notes_detect    = c("BQL"))

# This will show you the first one:
span_res$tables[["Table 1"]]$ft
#> a flextable object.
#> col_keys: `TIME`, `Analyte`, `1`, `2`, `3`, `4`, `5`, `6` 
#> header has 2 row(s) 
#> body has 20 row(s) 
#> original dataset sample: 
#>   TIME   Analyte    1    2     3    4    5     6
#> 1    0 Biomarker 1250 1030   831 1170 1140   868
#> 2 0.25 Biomarker 1255 1032 832.2 1172 1145 869.4
#> 3  0.5 Biomarker 1259 1034 833.4 1174 1149 870.9
#> 4    1 Biomarker 1269 1037 835.8 1178 1158 873.7
#> 5    2 Biomarker 1287 1045 840.5 1186 1176 879.4

# This will build a single table with the rows and 
# column ranges specified
bs_res =   build_span(table_body      = table_body,
                      row_common      = row_common,
                      table_body_head = table_body_head,
                      row_common_head = row_common_head,
                      col_sel         = c(1:10),
                      row_sel         = c(1:10),
                      notes_detect    = c("BQL"))

# This will show you the result:
bs_res$ft
#> a flextable object.
#> col_keys: `TIME`, `Analyte`, `1`, `2`, `3`, `4`, `5`, `6`, `7`, `8`, `9`, `10` 
#> header has 2 row(s) 
#> body has 10 row(s) 
#> original dataset sample: 
#>   TIME   Analyte    1    2     3    4    5     6   7    8    9    10
#> 1    0 Biomarker 1250 1030   831 1170 1140   868 643 1050 1130   744
#> 2 0.25 Biomarker 1255 1032 832.2 1172 1145 869.4 644 1051 1134 745.9
#> 3  0.5 Biomarker 1259 1034 833.4 1174 1149 870.9 645 1052 1138 747.8
#> 4    1 Biomarker 1269 1037 835.8 1178 1158 873.7 647 1055 1146 751.7
#> 5    2 Biomarker 1287 1045 840.5 1186 1176 879.4 651 1059 1162 759.2