The hardware and bandwidth for this mirror is donated by dogado GmbH, the Webhosting and Full Service-Cloud Provider. Check out our Wordpress Tutorial.
If you wish to report a bug, or if you are interested in having us mirror your free-software or open-source project, please feel free to contact us at mirror[@]dogado.de.
This vignette walks through a program in a fuller context. Here we’re going to create a simple demographics table.
First we’ll start by preparing the data. We’ll use our other package {Tplyr} to take care of the summaries.
library(clinify)
library(Tplyr)
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
tplyr_adsl <- tplyr_adsl |>
mutate(
SEX = recode(SEX, M = "Male", F = "Female"),
RACE = factor(
RACE,
c(
"AMERICAN INDIAN OR ALASKA NATIVE",
"ASIAN",
"BLACK OR AFRICAN AMERICAN",
"NATIVE HAWAIIN OR OTHER PACIFIC ISLANDER",
"WHITE",
"MULTIPLE"
)
)
)
t <- tplyr_table(tplyr_adsl, TRT01P) |>
add_layer(
group_count(SEX, by = "Sex n (%)") |>
set_missing_count(f_str("xx", n), Missing = NA, denom_ignore = TRUE)
) |>
add_layer(
group_desc(AGE, by = "Age (Years)")
) |>
add_layer(
group_count(AGEGR1, by = "Age Categories n (%)") |>
set_missing_count(f_str("xx", n), Missing = NA, denom_ignore = TRUE)
) |>
add_layer(
group_count(RACE, by = "Race n (%)") |>
set_missing_count(f_str("xx", n), Missing = NA, denom_ignore = TRUE) |>
set_order_count_method("byfactor")
) |>
add_layer(
group_count(ETHNIC, by = "Ethnicity n (%)") |>
set_missing_count(f_str("xx", n), Missing = NA, denom_ignore = TRUE)
) |>
add_layer(
group_desc(HEIGHTBL, by = "Height at Baseline")
) |>
add_layer(
group_desc(WEIGHTBL, by = "Weight at Baseline")
)
# Apply some conditional formatting for blanking out 0's.
dat <- build(t) |>
mutate(
across(
starts_with("var"),
~ if_else(
ord_layer_index %in% c(1, 3:5),
apply_conditional_format(
string = .,
format_group = 2,
condition = x == 0,
replacement = ""
),
.
)
)
)
# Sort all the row values out, add row masks and breaks
dat <- dat |>
arrange(ord_layer_index, ord_layer_1, ord_layer_2) |>
apply_row_masks() |>
select(
starts_with("row_label"),
var1_Placebo,
`var1_Xanomeline Low Dose`,
`var1_Xanomeline High Dose`,
ord_layer_index
)
# Grab the header Ns for column header help
header_n <- t$header_n$n
names(header_n) <- t$header_n$TRT01P
Great - our data are presentation ready now. Using {clinify} we’ll get everything ready. Looking at some of these sections:
clin_auto_page()
to let Word figure out page
breaks for us.clin_column_headers()
. We
grabbed our header N’s from {Tplyr} and inserted them here.clintable
to do this.clin_col_widths()
by using
a proportion of the total desired table width.{PAGE}
and {NUMPAGES}
.ct <- clintable(dat) |>
# Use group changes to let Word naturally split pages
clin_auto_page("ord_layer_index", drop = TRUE) |>
# Add padding to changes within the group
# By using `notempty`, paging groups are determined by populated
# values of `row_label1`
clin_group_pad('row_label1', when = "notempty") |>
# Assign column headers with spanning rows
clin_column_headers(
row_label1 = "",
row_label2 = "",
var1_Placebo = sprintf("Placebo\n(N=%s)", header_n["Placebo"]),
`var1_Xanomeline Low Dose` = c(
"Xanomeline",
sprintf("Low Dose\n(N=%s)", header_n["Xanomeline Low Dose"])
),
`var1_Xanomeline High Dose` = c(
"Xanomeline",
sprintf("High Dose\n(N=%s)", header_n["Xanomeline High Dose"])
)
) |>
# Use flextable functions directly to set all of the alignment
flextable::align(align = "center", part = "header") |>
flextable::align(
j = c(
"var1_Placebo",
"var1_Xanomeline Low Dose",
"var1_Xanomeline High Dose"
),
align = "center"
) |>
# Set column widths as proportion of the total document width
clin_col_widths(
row_label1 = .17,
row_label2 = .3,
var1_Placebo = .176,
`var1_Xanomeline Low Dose` = .176,
`var1_Xanomeline High Dose` = .176
) |>
# Add titles here is using new_header_footer to allow flextable functions
# to customize the titles block
clin_add_titles(
list(
# We'll add tools to automate paging
c("Protocol: CDISCPILOT01", "Page {PAGE} of {NUMPAGES}"),
c("Table 14-2.01"),
c("Summary of Demographic and Baseline Characteristics")
)
) |>
clin_add_footnotes(
list(
c(
"Source: /my/file/path.R",
format(Sys.time(), "%H:%M %A, %B %d, %Y")
)
)
)
print(ct)
Protocol: CDISCPILOT01 | Page of |
Table 14-2.01 | |
Summary of Demographic and Baseline Characteristics |
| Xanomeline | Xanomeline | ||
---|---|---|---|---|
Placebo | Low Dose | High Dose | ||
Sex n (%) | Female | 53 ( 61.6%) | 50 ( 59.5%) | 40 ( 47.6%) |
Male | 33 ( 38.4%) | 34 ( 40.5%) | 44 ( 52.4%) | |
Missing | 0 | 0 | 0 | |
Age (Years) | n | 86 | 84 | 84 |
Mean (SD) | 75.2 ( 8.59) | 75.7 ( 8.29) | 74.4 ( 7.89) | |
Median | 76.0 | 77.5 | 76.0 | |
Q1, Q3 | 69.2, 81.8 | 71.0, 82.0 | 70.8, 80.0 | |
Min, Max | 52, 89 | 51, 88 | 56, 88 | |
Missing | 0 | 0 | 0 | |
Age Categories n (%) | 65-80 | 42 ( 48.8%) | 47 ( 56.0%) | 55 ( 65.5%) |
<65 | 14 ( 16.3%) | 8 ( 9.5%) | 11 ( 13.1%) | |
>80 | 30 ( 34.9%) | 29 ( 34.5%) | 18 ( 21.4%) | |
Missing | 0 | 0 | 0 | |
Race n (%) | AMERICAN INDIAN OR ALASKA NATIVE | 0 | 0 | 1 ( 1.2%) |
ASIAN | 0 | 0 | 0 |
Source: /my/file/path.R | 13:38 Monday, July 07, 2025 |
With everything ready to go, we can write our table out to its
destination using write_clindoc()
.
These binaries (installable software) and packages are in development.
They may not be fully stable and should be used with caution. We make no claims about them.
Health stats visible at Monitor.