In this vignette we focus on providing more explanation on how the inTextSummaryTable
package actually works. We would describe some of the functionalities less exposed to the users.
We assume you are already familiar on how to create and export tables, otherwise we advise to first check out the dedicated vignettes for creating and exporting tables. The vignettes are accessible with the commands below.
vignette("inTextSummaryTable-createTables", "inTextSummaryTable")
vignette("inTextSummaryTable-exportTables", "inTextSummaryTable")
We will first create example data sets to show how the exporting functionalities work. The data sets used are available in the clinUtils
package.
library(inTextSummaryTable)
library(clinUtils)
library(pander)
library(tools) # toTitleCase
# load example data
data(dataADaMCDISCP01)
dataAll <- dataADaMCDISCP01
labelVars <- attr(dataAll, "labelVars")
dataADSL <- dataADaMCDISCP01$ADSL
dataAE <- subset(dataAll$ADAE, SAFFL == "Y" & TRTEMFL == "Y")
dataAEInterest <- subset(dataAE, AESOC %in% c(
"INFECTIONS AND INFESTATIONS",
"GENERAL DISORDERS AND ADMINISTRATION SITE CONDITIONS"
)
)
# ensure that order of elements is the one specified in
# the corresponding numeric variable
dataAEInterest$TRTA <- reorder(dataAEInterest$TRTA, dataAEInterest$TRTAN)
dataAEInterest$AESEV <- factor(dataAEInterest$AESEV, levels = c("MILD", "MODERATE"))
dataTotalAE <- subset(dataAll$ADSL, TRT01A != "Placebo")
# should contain columns specified in 'colVar'
dataTotalAE$TRTA <- dataTotalAE$TRT01A
The getSummaryStatisticsTable
consists of the following framework:
computeSummaryStatisticsTable
functionoutputType
parameterThe supporting data for the summary statistics table, is accessed via the computeSummaryStatisticsTable
. This includes the entire set of statistics (as numeric) and combined statistic set.
The output from the computeSummaryStatisticsTable
is equivalent of the table output by the getSummaryStatisticsTable
function when the outputType
is set to ‘data.frame-base’.
summaryTable <- computeSummaryStatisticsTable(
data = dataAEInterest,
rowVar = c("AESOC", "AEDECOD"),
rowVarTotalInclude = c("AESOC", "AEDECOD"),
colVar = "TRTA",
stats = getStats("n (%)"),
dataTotal = dataTotalAE,
labelVars = labelVars,
rowVarLab = c('AESOC' = "TEAE by SOC and Preferred Term\nn (%)")
)
pander(head(summaryTable, 3))
AESOC | AEDECOD |
---|---|
GENERAL DISORDERS AND ADMINISTRATION SITE CONDITIONS | APPLICATION SITE DERMATITIS |
GENERAL DISORDERS AND ADMINISTRATION SITE CONDITIONS | APPLICATION SITE ERYTHEMA |
GENERAL DISORDERS AND ADMINISTRATION SITE CONDITIONS | APPLICATION SITE IRRITATION |
TRTA | isTotal | statN | statm | statPercTotalN | statPercN |
---|---|---|---|---|---|
Xanomeline Low Dose | FALSE | 0 | 0 | 2 | 0 |
Xanomeline Low Dose | FALSE | 2 | 2 | 2 | 100 |
Xanomeline Low Dose | FALSE | 1 | 2 | 2 | 50 |
n (%) |
---|
0 |
2 (100) |
1 (50.0) |
Please note the presence of the isTotal
column, which flags the records containing the number of subjects reported in the table header.
pander(subset(summaryTable, isTotal))
AESOC | AEDECOD | TRTA | isTotal | statN | statm | |
---|---|---|---|---|---|---|
13 | NA | NA | Xanomeline Low Dose | TRUE | 2 | 2 |
26 | NA | NA | Xanomeline High Dose | TRUE | 3 | 3 |
statPercTotalN | statPercN | n (%) | |
---|---|---|---|
13 | 2 | 100 | 2 (100) |
26 | 3 | 100 | 3 (100) |
The summary table is exported to the format of interest with:
export(
summaryTable = summaryTable,
outputType = "flextable"
)
TEAE by SOC and Preferred Term | Xanomeline Low Dose | Xanomeline High Dose |
---|---|---|
Dictionary-Derived Term | ||
Any TEAE by SOC and Preferred Term | 2 (100) | 3 (100) |
GENERAL DISORDERS AND ADMINISTRATION SITE CONDITIONS | 2 (100) | 3 (100) |
APPLICATION SITE DERMATITIS | 0 | 1 (33.3) |
APPLICATION SITE ERYTHEMA | 2 (100) | 1 (33.3) |
APPLICATION SITE IRRITATION | 1 (50.0) | 1 (33.3) |
APPLICATION SITE PRURITUS | 2 (100) | 2 (66.7) |
FATIGUE | 0 | 1 (33.3) |
SECRETION DISCHARGE | 1 (50.0) | 0 |
SUDDEN DEATH | 1 (50.0) | 0 |
INFECTIONS AND INFESTATIONS | 1 (50.0) | 1 (33.3) |
LOWER RESPIRATORY TRACT INFECTION | 0 | 1 (33.3) |
PNEUMONIA | 1 (50.0) | 0 |
Please see the vignette: inTextSummaryTable-exportTables
for more information on the different export types available.
combine
functionSummary statistics tables can be combined with the combine
function.
tableDemoCat <- computeSummaryStatisticsTable(
data = dataADSL,
var = c("SEX", "AGE"), varInclude0 = TRUE,
colVar = "TRT01P",
stats = getStats("n (%)", includeName = FALSE),
labelVars = labelVars
)
tableDemoCont <- computeSummaryStatisticsTable(
data = dataADSL,
var = c("HEIGHTBL", "WEIGHTBL"),
colVar = "TRT01P",
stats = getStats(c("n", "Mean")),
labelVars = labelVars
)
tableDemo <- combine(tableDemoCat, tableDemoCont)
export(tableDemo)
Placebo | Xanomeline High Dose | Xanomeline Low Dose | |
---|---|---|---|
Sex | |||
F | 1 (50.0) | 2 (66.7) | 2 (100) |
M | 1 (50.0) | 1 (33.3) | 0 |
Age | 2 (100) | 3 (100) | 2 (100) |
Baseline Height (cm) | |||
n | 2 | 3 | 2 |
Mean | 167.7 | 163 | 155.6 |
Baseline Weight (kg) | |||
n | 2 | 3 | 2 |
Mean | 59.65 | 68.5 | 54.45 |
The tables created via the inTextSummaryTable
are simple R data.frame
objects, so these can be combined/update to include extra statistics of interest.
The general workflow is to:
computeSummaryStatisticsTable
function)data.frame
with your statistics of relevance - in a similar formatexportSummaryStatisticsTable
function)For example, we combine the descriptive statistics table created above with a set of pre-computed statistics (e.g. p-values of the difference between the treatment groups).
dataADSL$TRT01P <- with(dataADSL, reorder(TRT01P, TRT01PN))
# check format of table created with the package:
descTable <- tableDemoCont
descTable[, c("variable", "TRT01P", "isTotal", "n", "Mean")]
## variable TRT01P isTotal n Mean
## 1 Baseline Height (cm) Placebo FALSE 2 167.7
## 2 Baseline Weight (kg) Placebo FALSE 2 59.65
## 3 <NA> Placebo TRUE 2 NA
## 4 Baseline Height (cm) Xanomeline High Dose FALSE 3 163
## 5 Baseline Weight (kg) Xanomeline High Dose FALSE 3 68.5
## 6 <NA> Xanomeline High Dose TRUE 3 NA
## 7 Baseline Height (cm) Xanomeline Low Dose FALSE 2 155.6
## 8 Baseline Weight (kg) Xanomeline Low Dose FALSE 2 54.45
## 9 <NA> Xanomeline Low Dose TRUE 2 NA
# add p-values in an extra row
infTable <- unique(subset(descTable, !isTotal)[, c("variable", "TRT01P"), drop = FALSE])
infTable[which(infTable$variable == "Baseline Height (cm)"), "pValue"] <- 1e-10
infTable[which(infTable$variable == "Baseline Weight (kg)"), "pValue"] <- 1e-9
summaryTable <- plyr::rbind.fill(descTable, infTable)
exportSummaryStatisticsTable(
summaryTable = summaryTable,
rowVar = "variable",
colVar = "TRT01P",
statsVar = c("n", "Mean", "pValue")
)
variable | Placebo | Xanomeline High Dose | Xanomeline Low Dose |
---|---|---|---|
Baseline Height (cm) | |||
n | 2 | 3 | 2 |
Mean | 167.7 | 163 | 155.6 |
pValue | 1e-10 | 1e-10 | 1e-10 |
Baseline Weight (kg) | |||
n | 2 | 3 | 2 |
Mean | 59.65 | 68.5 | 54.45 |
pValue | 1e-09 | 1e-09 | 1e-09 |
compLab <- "Comparison between treatments (p-value)"
# add p-values in a new column - in an extra row
infTable <- unique(subset(descTable, !isTotal)[, "variable", drop = FALSE])
infTable$TRT01P <- compLab
infTable[which(infTable$variable == "Baseline Height (cm)"), "pValue"] <- 1e-10
infTable[which(infTable$variable == "Baseline Weight (kg)"), "pValue"] <- 1e-9
summaryTable <- plyr::rbind.fill(descTable, infTable)
# order columns to have comparison column as last
summaryTable$TRT01P <- factor(summaryTable$TRT01P, levels = c(levels(dataADSL$TRT01P), compLab))
exportSummaryStatisticsTable(
summaryTable = summaryTable,
rowVar = "variable",
colVar = "TRT01P",
statsVar = c("n", "Mean", "pValue")
)
variable | Placebo | Xanomeline Low Dose | Xanomeline High Dose | Comparison between treatments (p-value) |
---|---|---|---|---|
Baseline Height (cm) | ||||
n | 2 | 2 | 3 | - |
Mean | 167.7 | 155.6 | 163 | - |
pValue | - | - | - | 1e-10 |
Baseline Weight (kg) | ||||
n | 2 | 2 | 3 | - |
Mean | 59.65 | 54.45 | 68.5 | - |
pValue | - | - | - | 1e-09 |
infTable <- unique(subset(descTable, !isTotal)[, "variable", drop = FALSE])
infTable$TRT01P <- compLab
infTable[which(infTable$variable == "Baseline Height (cm)"), "Mean"] <- 1e-10
infTable[which(infTable$variable == "Baseline Weight (kg)"), "Mean"] <- 1e-9
summaryTable <- plyr::rbind.fill(descTable, infTable)
# order columns to have comparison column as last
summaryTable$TRT01P <- factor(summaryTable$TRT01P, levels = c(levels(dataADSL$TRT01P), compLab))
exportSummaryStatisticsTable(
summaryTable = summaryTable,
rowVar = "variable",
colVar = "TRT01P",
statsVar = c("n", "Mean")
)
variable | Placebo | Xanomeline Low Dose | Xanomeline High Dose | Comparison between treatments (p-value) |
---|---|---|---|---|
Baseline Height (cm) | ||||
n | 2 | 2 | 3 | - |
Mean | 167.7 | 155.6 | 163 | 1e-10 |
Baseline Weight (kg) | ||||
n | 2 | 2 | 3 | - |
Mean | 59.65 | 54.45 | 68.5 | 1e-09 |
The variables used for the row and columns of the summary statistics tables should be present in a long format in the input data for the getSummaryStatisticsTable
function.
In case the grouping of the rows/columns is more complex and no grouping variable is yet available in the data, the function combineVariables
offers simpler functionalities to create the input data.
The label for the grouping is extracted from the SAS dataset labels if labelVars
is specified, or can be customized (label
parameter).
For example, the adverse events are counted for different population set: screened population, completer population, only events with high severity, or related to the treatment and with high severity.
# prepare the data: create grouping of interest
dataAEGroup <- combineVariables(
data = dataAEInterest,
newVar = "AEGRP",
paramsList = list(
# for all screened patients
list(var = "TRTA", value = "Xanomeline High Dose"),
# for moderate severity
list(var = "AESEV", value = "MODERATE", labelExtra = "Moderate"),
list(var = "AENDY", label = paste("With adverse events ending date"))
),
# include also counts for all records
includeAll = TRUE,
labelAll = "All Adverse events",
labelVars = labelVars
)
labelVars["AEGRP"] <- "Patient groups of interest"
# create the table
getSummaryStatisticsTable(
data = dataAEGroup,
colVar = "TRTA",
rowVar = "AEGRP",
labelVars = labelVars,
dataTotal = dataTotalAE,
stats = list(expression(paste0(statN, " (", round(statPercN, 1), ")"))),
title = "Table: Adverse events: counts for groups of interest",
footer = "Statistics: n (%)"
)
Table: Adverse events: counts for groups of interest | |||
---|---|---|---|
Patient groups of interest | Xanomeline Low Dose | Xanomeline High Dose | |
All Adverse events | 2 (100) | 3 (100) | 0 (NA) |
Actual Treatment | 0 (0) | 3 (100) | 0 (NA) |
Severity/Intensity Moderate | 1 (50) | 3 (100) | 0 (NA) |
With adverse events ending date | 2 (100) | 3 (100) | 0 (NA) |
Statistics: n (%) |
R version 4.4.0 (2024-04-24)
Platform: x86_64-pc-linux-gnu
locale: C
attached base packages: tools, stats, graphics, grDevices, utils, datasets, methods and base
other attached packages: pander(v.0.6.5), clinUtils(v.0.2.0), inTextSummaryTable(v.3.3.3) and knitr(v.1.47)
loaded via a namespace (and not attached): gtable(v.0.3.5), xfun(v.0.44), bslib(v.0.7.0), ggplot2(v.3.5.1), htmlwidgets(v.1.6.4), ggrepel(v.0.9.5), vctrs(v.0.6.5), crosstalk(v.1.2.1), generics(v.0.1.3), curl(v.5.2.1), tibble(v.3.2.1), fansi(v.1.0.6), pkgconfig(v.2.0.3), data.table(v.1.15.4), uuid(v.1.2-0), lifecycle(v.1.0.4), flextable(v.0.9.6), stringr(v.1.5.1), compiler(v.4.4.0), textshaping(v.0.4.0), munsell(v.0.5.1), httpuv(v.1.6.15), fontquiver(v.0.2.1), fontLiberation(v.0.1.0), htmltools(v.0.5.8.1), sass(v.0.4.9), yaml(v.2.3.8), later(v.1.3.2), pillar(v.1.9.0), crayon(v.1.5.2), jquerylib(v.0.1.4), gfonts(v.0.2.0), openssl(v.2.2.0), DT(v.0.33), cachem(v.1.1.0), mime(v.0.12), fontBitstreamVera(v.0.1.1), tidyselect(v.1.2.1), zip(v.2.3.1), digest(v.0.6.35), stringi(v.1.8.4), reshape2(v.1.4.4), dplyr(v.1.1.4), forcats(v.1.0.0), cowplot(v.1.1.3), fastmap(v.1.2.0), grid(v.4.4.0), colorspace(v.2.1-0), cli(v.3.6.2), magrittr(v.2.0.3), crul(v.1.4.2), utf8(v.1.2.4), gdtools(v.0.3.7), scales(v.1.3.0), promises(v.1.3.0), rmarkdown(v.2.27), officer(v.0.6.6), askpass(v.1.2.0), ragg(v.1.3.2), hms(v.1.1.3), shiny(v.1.8.1.1), evaluate(v.0.24.0), haven(v.2.5.4), viridisLite(v.0.4.2), rlang(v.1.1.4), Rcpp(v.1.0.12), xtable(v.1.8-4), glue(v.1.7.0), httpcode(v.0.3.0), xml2(v.1.3.6), jsonlite(v.1.8.8), R6(v.2.5.1), plyr(v.1.8.9) and systemfonts(v.1.1.0)