The format set of functions can be combined to format a summarised_result object (see R package omopgenerics) into a nice tibble, flextable or gt table to display in reports and shiny apps.
The functions formatEstimateValue()
,
formatEstimateName()
, formatHeader()
, and
lastly formatTable()
can be implemented in a pipeline to
obtain the desired formatted table. Otherwise, these steps are
implemented in the function visOmopTable()
.
Formatting functions in a pipeline
First, we load the relevant libraries and generate a summarised_result with mock results.
library(visOmopResults)
library(dplyr)
mock_sr <- mockSummarisedResult()
mock_sr |> glimpse()
1. formatEstimateValue()
This function provides tools to format the estimate_value column:
choose number of decimals to display for each estimate_type or
estimate_name (decimals
), and change change the decimal
and thousand/million separator mark (decimalMark
and
bigMark
respectively)
By default, decimals of integer values are set to 0, numeric to 2, percentage to 1, and proportion to 3. The defaulted decimal mark is “.” while the thousand/million separator is “,”.
mock_sr <- mock_sr |> formatEstimateValue()
mock_sr |> glimpse()
If we want the same number of decimals for all the estimates, instead
of a named vector the decimal
argument can be a numeric
pointing the number of decimals.
2. formatEstimateName()
We can customise estimate display by changing the estimate name and joining different estimates in the same row. For instance, we can display counts and percentages together as “N (%)”.
The estimateNameFormat
is where combinations can be
specified. Values from estimate_name’s column should be
specified between <…>. The new estimate_name will be the
names of this vector, or the value itself when it is not named.
mock_sr <- mock_sr |>
formatEstimateName(
estimateNameFormat = c(
"N (%)" = "<count> (<percentage>%)",
"N" = "<count>",
"Mean (SD)" = "<mean> (<sd>)"
),
keepNotFormatted = FALSE,
useFormatOrder = FALSE
)
mock_sr |> glimpse()
Additional input arguments are keepNotFormatted
to
specify whether not formatted rows should be returned or dropped. If
useFormatOrder
is TRUE, estimates will be presented in the
order given in estimateNameFormat
, if FALSE, the original
order will be kept (where there is more than one estimate, the new
position will be the first of the estimates being merged).
3. formatHeader()
This function helps to create a nice header for a flextable or gt table. For instance, instead of having a column specifying the group name and level, we might one them in the header.
Header keys: there are 3 different types of headers, identified with the keys “header”, “header_name”, and “header_level”.
-
header: Header labels passed to
header
but which are not part of the input table (are not columns names or values). - header_name: Header labels that come from column names in the input table.
- header_level: Header labels that come from values of selected columns in the input table.
For instance, we might want to pivot by “group_level” and have an upper header called “Names of the cohorts”. To do that we would proceed as follows:
mock_sr |>
formatHeader(
header = c("Names of the cohorts", "group_level"),
delim = "\n",
includeHeaderName = TRUE,
includeHeaderKey = TRUE
) |>
glimpse()
The label keys can be removed with includeHeaderKey
set
to FALSE. However, having these keys in our header will allow to style
separately the different header types in the next step
(fxTable
and gtTable
). If we wish to remove
the header pointing to the column name (group_level), we can
set includeHeaderName
to FALSE.
Continuing with our example, we want to pivot by strata (name and level), but, we do not want the column names (that is, strata_name and strata_level) to appear in the header:
mock_sr <- mock_sr |>
mutate(across(c("strata_name", "strata_level"), ~ gsub("&&&", "and", .x))) |>
formatHeader(
header = c("Stratifications", "strata_name", "strata_level"),
delim = "\n",
includeHeaderName = FALSE,
includeHeaderKey = TRUE
)
mock_sr |> glimpse()
Notice, how we substitute the keyWord “&&&” to “and”, to get a nice header.
4. gtTable() and fxTable()
Finally, we have the functions gtTable
and
fxTable
which will transform our tibble into a gt
or flextable object respectively. These functions provide
several tools to personalise the formatted table.
gtTable()
Let’s start by manipulating the dataframe to have the columns that we
want to display, and then use gtTable
with default
values:
# first we select the columns we want:
mock_sr <- mock_sr |>
splitGroup() |>
select(!all_of(c(
"cdm_name", "estimate_type", "result_id","additional_name",
"additional_level"
)))
mock_sr |> gtTable()
Now, we want to group results by “cohort_name”. More specifically we
want to have a row which the name of each cohort before the results of
that cohort, and that cohort1 comes before cohort2.
Additionally, we want to merge those rows what contain the same
information for all the columns. To get this table we will use
gtTable
as follows:
mock_sr |>
gtTable(
groupColumn = "cohort_name",
groupAsColumn = FALSE,
groupOrder = c("cohort1", "cohort2"),
merge = "all_columns"
)
We might also want to modify the default style of the table. For
instance, we might want to highlight the cohort_name labels with a blue
background, have the body text in red, and use a combination of orange
and yellow for the header. We can do it with the style
argument:
mock_sr |>
gtTable(
style = list(
"header" = list(gt::cell_text(weight = "bold"),
gt::cell_fill(color = "orange")),
"header_level" = list(gt::cell_text(weight = "bold"),
gt::cell_fill(color = "yellow")),
"column_name" = gt::cell_text(weight = "bold"),
"group_label" = list(gt::cell_fill(color = "blue"),
gt::cell_text(color = "white", weight = "bold")),
"body" = gt::cell_text(color = "red")
),
groupColumn = "cohort_name",
groupAsColumn = FALSE,
groupOrder = c("cohort1", "cohort2"),
merge = "all_columns"
)
fxTable()
To obtain a similar result but with a flextable object, we
can use fxTable
with the same arguments as before, however,
style
must be adapted to use the officer package
since it is the accepted by flextable.
mock_sr |>
fxTable(
style = list(
"header" = list(
"cell" = officer::fp_cell(background.color = "orange"),
"text" = officer::fp_text(bold = TRUE)),
"header_level" = list(
"cell" = officer::fp_cell(background.color = "yellow"),
"text" = officer::fp_text(bold = TRUE)),
"column_name" = list("text" = officer::fp_text(bold = TRUE)),
"group_label" = list(
"cell" = officer::fp_cell(background.color = "blue"),
"text" = officer::fp_text(bold = TRUE, color = "white")),
"body" = list("text" = officer::fp_text(color = "red"))
),
groupColumn = "cohort_name",
groupAsColumn = FALSE,
groupOrder = c("cohort1", "cohort2"),
merge = "all_columns"
)
visOmopTable(): all at once
This function wraps the tools seen so far to format a summarised result at once. While it is convenient to have it all in one function, the level of table manipulation allowed is less than with the pipeline.
First, we create a new mock summarised result:
mock_sr2 <- mockSummarisedResult()
For instance, if we want to have a flextable with strata as header,
we will write “strata” in header
instead of
strata_name and strata_level. Same as before, we can
input header keys (e.g. “Stratifications” in the example below).
The split
argument points to which name-level columns to
split (group, strata and/or additional). Refer to the vignette split and
unite for further information on this functionality.
mock_sr2 |> visOmopTable(
formatEstimateName = c("N%" = "<count> (<percentage>)",
"N" = "<count>",
"Mean (SD)" = "<mean> (<sd>)"),
header = c("Stratifications", "strata")
)
By default, it returns a gt table, but it can be changed to
“flextable” and “tibble” in the type
argument.
The groupColumn
can be used to create groups in the
table body. For instance, looking at the previous table, we might want
to group by cohort name:
mock_sr2 |> visOmopTable(
formatEstimateName = c("N%" = "<count> (<percentage>)",
"N" = "<count>",
"Mean (SD)" = "<mean> (<sd>)"),
header = c("Stratifications", "strata"),
split = c("group","additional"),
groupColumn = "cohort_name"
)
Additional options can be specified in the .options
argument. These options are taken from the other format functions and
gt/fx table functions seen before. To see a list of allowed arguments
and their default values use optionsTable()
: