Demography Table
For this demography table we are going to use
data_demog
, an example analysis results dataset found in
the package, which is based on the CDISC pilot data. This dataset has
two different row label columns, rowlbl1
and
rowlbl2
because we are building a table with group and row
labels. There are also two order columns which will be used to set the
row order of the output. There is a single column to define our table’s
columns (multiple column columns are used when there is column
spanning). Finally there is a param column, a value column and an
additional grouping column, grp
, which we can use for more
complex formatting.
#> # A tibble: 6 × 8
#> # Groups: rowlbl1 [1]
#> rowlbl1 rowlbl2 param grp ord1 ord2 column value
#> <chr> <chr> <chr> <chr> <dbl> <dbl> <chr> <dbl>
#> 1 Age (y) n n cont 1 1 Placebo 86
#> 2 Age (y) n n cont 1 1 Xanomeline Low Dose 84
#> 3 Age (y) n n cont 1 1 Xanomeline High Dose 84
#> 4 Age (y) n n cont 1 1 Total 254
#> 5 Age (y) n p cont 1 1 p-value 0.593
#> 6 Age (y) Mean Mean cont 1 2 Placebo 75.2
The mock we are going to match looks like this:
Placebo | Xanomeline Low Dose | Xanomeline High Dose | Total | p-value | ||
---|---|---|---|---|---|---|
Age (y) | n | xxx | xxx | xxx | xxx | x.xxx |
Mean | xxx.x | xxx.x | xxx.x | xxx.x | ||
SD | xxx.xx | xxx.xx | xxx.xx | xxx.xx | ||
Median | xxx.x | xxx.x | xxx.x | xxx.x | ||
Min | xxx.x | xxx.x | xxx.x | xxx.x | ||
Max | xxx.x | xxx.x | xxx.x | xxx.x | ||
<65 yrs | xxx (xx.x %) | xxx (xx.x %) | xxx (xx.x %) | xxx (xx.x %) | x.xxx | |
65-80 yrs | xxx (xx.x %) | xxx (xx.x %) | xxx (xx.x %) | xxx (xx.x %) | ||
>80 yrs | xxx (xx.x %) | xxx (xx.x %) | xxx (xx.x %) | xxx (xx.x %) | ||
Sex | n | xxx | xxx | xxx | xxx | x.xxx |
Male | xxx (xx.x %) | xxx (xx.x %) | xxx (xx.x %) | xxx (xx.x %) | ||
Female | xxx (xx.x %) | xxx (xx.x %) | xxx (xx.x %) | xxx (xx.x %) | ||
Race (Origin) | n | xxx | xxx | xxx | xxx | x.xxx |
Caucasian | xxx (xx.x %) | xxx (xx.x %) | xxx (xx.x %) | xxx (xx.x %) | ||
African Descent | xxx (xx.x %) | xxx (xx.x %) | xxx (xx.x %) | xxx (xx.x %) | ||
Hispanic | xxx (xx.x %) | xxx (xx.x %) | xxx (xx.x %) | xxx (xx.x %) | ||
Other | xxx (xx.x %) | xxx (xx.x %) | xxx (xx.x %) | xxx (xx.x %) | ||
MMSE | n | xxx | xxx | xxx | xxx | x.xxx |
Mean | xxx.x | xxx.x | xxx.x | xxx.x | ||
SD | xxx.xx | xxx.xx | xxx.xx | xxx.xx | ||
Median | xxx.x | xxx.x | xxx.x | xxx.x | ||
Min | xxx.x | xxx.x | xxx.x | xxx.x | ||
Max | xxx.x | xxx.x | xxx.x | xxx.x | ||
Duration of disease | n | xxx | xxx | xxx | xxx | x.xxx |
Mean | xxx.x | xxx.x | xxx.x | xxx.x | ||
SD | xxx.xx | xxx.xx | xxx.xx | xxx.xx | ||
Median | xxx.x | xxx.x | xxx.x | xxx.x | ||
Min | xxx.x | xxx.x | xxx.x | xxx.x | ||
Max | xxx.x | xxx.x | xxx.x | xxx.x | ||
<12 months | xxx (xx.x %) | xxx (xx.x %) | xxx (xx.x %) | xxx (xx.x %) | x.xxx | |
>=12 months | xxx (xx.x %) | xxx (xx.x %) | xxx (xx.x %) | xxx (xx.x %) | ||
Years of education | n | xxx | xxx | xxx | xxx | x.xxx |
Mean | xxx.x | xxx.x | xxx.x | xxx.x | ||
SD | xxx.xx | xxx.xx | xxx.xx | xxx.xx | ||
Median | xxx.x | xxx.x | xxx.x | xxx.x | ||
Min | xxx.x | xxx.x | xxx.x | xxx.x | ||
Max | xxx.x | xxx.x | xxx.x | xxx.x | ||
Baseline weight(kg) | n | xxx | xxx | xxx | xxx | x.xxx |
Mean | xxx.x | xxx.x | xxx.x | xxx.x | ||
SD | xxx.xx | xxx.xx | xxx.xx | xxx.xx | ||
Median | xxx.x | xxx.x | xxx.x | xxx.x | ||
Min | xxx.x | xxx.x | xxx.x | xxx.x | ||
Max | xxx.x | xxx.x | xxx.x | xxx.x | ||
Baseline height(cm) | n | xxx | xxx | xxx | xxx | x.xxx |
Mean | xxx.x | xxx.x | xxx.x | xxx.x | ||
SD | xxx.xx | xxx.xx | xxx.xx | xxx.xx | ||
Median | xxx.x | xxx.x | xxx.x | xxx.x | ||
Min | xxx.x | xxx.x | xxx.x | xxx.x | ||
Max | xxx.x | xxx.x | xxx.x | xxx.x | ||
Baseline BMI | n | xxx | xxx | xxx | xxx | x.xxx |
Mean | xxx.x | xxx.x | xxx.x | xxx.x | ||
SD | xxx.xx | xxx.xx | xxx.xx | xxx.xx | ||
Median | xxx.x | xxx.x | xxx.x | xxx.x | ||
Min | xxx.x | xxx.x | xxx.x | xxx.x | ||
Max | xxx.x | xxx.x | xxx.x | xxx.x | ||
<25 | xxx (xx.x %) | xxx (xx.x %) | xxx (xx.x %) | xxx (xx.x %) | x.xxx | |
25-<30 | xxx (xx.x %) | xxx (xx.x %) | xxx (xx.x %) | xxx (xx.x %) | ||
>=30 | xxx (xx.x %) | xxx (xx.x %) | xxx (xx.x %) | xxx (xx.x %) | ||
For this table, we have three columns for each of the treatment groups, a total column for all groups combined, and a p-value column. The table also contains a mix of categorical and continuous analysis.
The first thing we are going to do when building out the
tfrmt
is specify all our columns
tfrmt(
# specify columns in the data
group = c(rowlbl1,grp),
label = rowlbl2,
column = column,
param = param,
value = value,
sorting_cols = c(ord1, ord2)) %>%
print_to_gt(data_demog) %>%
tab_options(
container.width = 900
)
ord1 | ord2 | Placebo | Xanomeline Low Dose | Xanomeline High Dose | Total | p-value | |
---|---|---|---|---|---|---|---|
Age (y) | |||||||
cont | |||||||
n | 1 | 1 | 86 | 84 | 84 | 254 | 0.593435775283097 |
Mean | 1 | 2 | 75.2093023255814 | 75.6666666666667 | 74.3809523809524 | 75.0866141732283 | NA |
SD | 1 | 3 | 8.59016712714193 | 8.28605059954093 | 7.88609384869824 | 8.24623389621606 | NA |
Median | 1 | 4 | 76 | 77.5 | 76 | 77 | NA |
Min | 1 | 5 | 52 | 51 | 56 | 51 | NA |
Max | 1 | 6 | 89 | 88 | 88 | 89 | NA |
cat | |||||||
<65 yrs | 1 | 7 | 14, 16.2790697674419 | 8, 9.52380952380952 | 11, 13.0952380952381 | 33, 12.992125984252 | 0.143917025502502 |
65-80 yrs | 1 | 8 | 42, 48.8372093023256 | 47, 55.9523809523809 | 55, 65.4761904761905 | 144, 56.6929133858268 | NA |
>80 yrs | 1 | 9 | 30, 34.8837209302326 | 29, 34.5238095238095 | 18, 21.4285714285714 | 77, 30.3149606299213 | NA |
Sex | |||||||
cat | |||||||
n | 2 | 1 | 86 | 84 | 84 | 254 | 0.140859828596478 |
Male | 2 | 2 | 33, 38.3720930232558 | 34, 40.4761904761905 | 44, 52.3809523809524 | 111, 43.7007874015748 | NA |
Female | 2 | 3 | 53, 61.6279069767442 | 50, 59.5238095238095 | 40, 47.6190476190476 | 143, 56.2992125984252 | NA |
Race (Origin) | |||||||
cat | |||||||
n | 3 | 1 | 86 | 84 | 84 | 254 | 0.647674941661787 |
Caucasian | 3 | 2 | 75, 87.2093023255814 | 72, 85.7142857142857 | 71, 84.5238095238095 | 218, 85.8267716535433 | NA |
African Descent | 3 | 3 | 8, 9.30232558139535 | 6, 7.14285714285714 | 9, 10.7142857142857 | 23, 9.05511811023622 | NA |
Hispanic | 3 | 4 | 3, 3.48837209302326 | 6, 7.14285714285714 | 3, 3.57142857142857 | 12, 4.7244094488189 | NA |
Other | 3 | 5 | NA, NA | NA, NA | 1, 1.19047619047619 | 1, 0.393700787401575 | NA |
MMSE | |||||||
cont | |||||||
n | 4 | 1 | 86 | 84 | 84 | 254 | 0.59465975941027 |
Mean | 4 | 2 | 18.046511627907 | 17.8690476190476 | 18.5119047619048 | 18.1417322834646 | NA |
SD | 4 | 3 | 4.2727783404855 | 4.22208696726523 | 4.15800591577738 | 4.21032874412179 | NA |
Median | 4 | 4 | 19.5 | 18 | 20 | 19 | NA |
Min | 4 | 5 | 10 | 10 | 10 | 10 | NA |
Max | 4 | 6 | 23 | 24 | 24 | 24 | NA |
Duration of disease | |||||||
cont | |||||||
n | 5 | 1 | 86 | 84 | 84 | 254 | 0.152960564175341 |
Mean | 5 | 2 | 42.65 | 48.6916666666667 | 40.5071428571429 | 43.9393700787402 | NA |
SD | 5 | 3 | 30.241571504451 | 29.5841711516636 | 24.6935472070355 | 28.3973156262964 | NA |
Median | 5 | 4 | 35.3 | 40.25 | 35.95 | 36.25 | NA |
Min | 5 | 5 | 7.2 | 7.8 | 2.2 | 2.2 | NA |
Max | 5 | 6 | 183.1 | 130.8 | 135 | 183.1 | NA |
cat | |||||||
<12 months | 5 | 7 | 5, 5.81395348837209 | 3, 3.57142857142857 | 4, 4.76190476190476 | 12, 4.7244094488189 | 0.788536928535063 |
>=12 months | 5 | 8 | 81, 94.1860465116279 | 81, 96.4285714285714 | 80, 95.2380952380952 | 242, 95.2755905511811 | NA |
Years of education | |||||||
cont | |||||||
n | 6 | 1 | 86 | 84 | 84 | 254 | 0.38750874992316 |
Mean | 6 | 2 | 12.5813953488372 | 13.1666666666667 | 12.5119047619048 | 12.751968503937 | NA |
SD | 6 | 3 | 2.94843973206596 | 4.14738510544312 | 2.91854910157261 | 3.3829227112292 | NA |
Median | 6 | 4 | 12 | 12 | 12 | 12 | NA |
Min | 6 | 5 | 6 | 3 | 6 | 3 | NA |
Max | 6 | 6 | 21 | 24 | 20 | 24 | NA |
Baseline weight(kg) | |||||||
cont | |||||||
n | 7 | 1 | 86 | 83 | 84 | 253 | 0.00304006274608553 |
Mean | 7 | 2 | 62.7593023255814 | 67.2795180722892 | 70.0047619047619 | 66.6478260869565 | NA |
SD | 7 | 3 | 12.7715435329253 | 14.1235986486909 | 14.6534333717795 | 14.1314255372792 | NA |
Median | 7 | 4 | 60.55 | 64.9 | 69.2 | 66.7 | NA |
Min | 7 | 5 | 34 | 45.4 | 41.7 | 34 | NA |
Max | 7 | 6 | 86.2 | 106.1 | 108 | 108 | NA |
Baseline height(cm) | |||||||
cont | |||||||
n | 8 | 1 | 86 | 84 | 84 | 254 | 0.126217916960126 |
Mean | 8 | 2 | 162.573255813953 | 163.433333333333 | 165.820238095238 | 163.931496062992 | NA |
SD | 8 | 3 | 11.5223611185188 | 10.4192400034262 | 10.1313515524819 | 10.7604472686284 | NA |
Median | 8 | 4 | 162.6 | 162.6 | 165.1 | 162.85 | NA |
Min | 8 | 5 | 137.2 | 135.9 | 146.1 | 135.9 | NA |
Max | 8 | 6 | 185.4 | 195.6 | 190.5 | 195.6 | NA |
Baseline BMI | |||||||
cont | |||||||
n | 9 | 1 | 86 | 83 | 84 | 253 | 0.0133190726378392 |
Mean | 9 | 2 | 23.6360465116279 | 25.0626506024096 | 25.347619047619 | 24.6723320158103 | NA |
SD | 9 | 3 | 3.67192569419556 | 4.27050893303881 | 4.15826876019846 | 4.09218492698334 | NA |
Median | 9 | 4 | 23.4 | 24.3 | 24.8 | 24.2 | NA |
Min | 9 | 5 | 15.1 | 17.7 | 13.7 | 13.7 | NA |
Max | 9 | 6 | 33.3 | 40.1 | 34.5 | 40.1 | NA |
cat | |||||||
<25 | 9 | 7 | 59, 68.6046511627907 | 47, 55.9523809523809 | 44, 52.3809523809524 | 150, 59.0551181102362 | 0.232621461976889 |
25-<30 | 9 | 8 | 21, 24.4186046511628 | 27, 32.1428571428571 | 28, 33.3333333333333 | 76, 29.9212598425197 | NA |
>=30 | 9 | 9 | 6, 6.97674418604651 | 10, 11.9047619047619 | 12, 14.2857142857143 | 28, 11.0236220472441 | NA |
While this makes a table, it isn’t a very nice table and definitely
doesn’t match the mock. So let’s start with formatting all the numbers.
To do this we are going to build a body_plan
to add to our
tfrmt
. This will be a fairly quick explanation of
body_plan
s but if you would like more information see
vignettes("Body Plan")
Body plans are made up of a series of frmt_stucture
s
where each frmt_stucture
represents the formatting of a
cell within the table. The order of the frmt_structure
s
matter; they are always applied latest to oldest. This means the first
frmt_stucture
in the body_plan
should be the
most generic. You can use the groups, labels and parameters to specify
which formatting applies to which values.
To start, we are going to use all the rows that are “n (%)” as the
default. This way we don’t need to list out every row that is an “n (%)”
row. These rows are made up of two different values, so we will need to
use frmt_combine
. Next, we can format the continuous
variables, which is just a straightforward one value per row so we can
just use the label to filter and frmt
to define the look.
Finally, we want to format the p-values. This is a bit more complicated,
since the p-value sits in the same row as other parameters; therefore
the group and label value are not specific enough and we need something
more granular. As such, we will need to specify the parameter in the
frmt_structure
like so:
frmt_structure(group_val = ".default", label_val = ".default", p = frmt("x.xx")
.
Further, we also need to make sure it never displays a rounded p-value
of 0 or 1. So we can use frmt_when
to specify the
formatting based on the value.
tfrmt(
# specify columns in the data
group = c(rowlbl1,grp),
label = rowlbl2,
column = column,
param = param,
value = value,
sorting_cols = c(ord1, ord2),
# specify value formatting
body_plan = body_plan(
frmt_structure(group_val = ".default", label_val = ".default", frmt_combine("{n} ({pct} %)",
n = frmt("xxx"),
pct = frmt("xx.x"))),
frmt_structure(group_val = ".default", label_val = "n", frmt("xxx")),
frmt_structure(group_val = ".default", label_val = c("Mean", "Median", "Min","Max"), frmt("xxx.x")),
frmt_structure(group_val = ".default", label_val = "SD", frmt("xxx.xx")),
frmt_structure(group_val = ".default", label_val = ".default", p = frmt_when(">0.99" ~ ">0.99",
"<0.001" ~ "<0.001",
TRUE ~ frmt("x.xxx", missing = "")))
)) %>%
print_to_gt(data_demog) %>%
tab_options(
container.width = 900
)
ord1 | ord2 | Placebo | Xanomeline Low Dose | Xanomeline High Dose | Total | p-value | |
---|---|---|---|---|---|---|---|
Age (y) | |||||||
cont | |||||||
n | 1 | 1 | 86 | 84 | 84 | 254 | 0.593 |
Mean | 1 | 2 | 75.2 | 75.7 | 74.4 | 75.1 | |
SD | 1 | 3 | 8.59 | 8.29 | 7.89 | 8.25 | |
Median | 1 | 4 | 76.0 | 77.5 | 76.0 | 77.0 | |
Min | 1 | 5 | 52.0 | 51.0 | 56.0 | 51.0 | |
Max | 1 | 6 | 89.0 | 88.0 | 88.0 | 89.0 | |
cat | |||||||
<65 yrs | 1 | 7 | 14 (16.3 %) | 8 ( 9.5 %) | 11 (13.1 %) | 33 (13.0 %) | 0.144 |
65-80 yrs | 1 | 8 | 42 (48.8 %) | 47 (56.0 %) | 55 (65.5 %) | 144 (56.7 %) | |
>80 yrs | 1 | 9 | 30 (34.9 %) | 29 (34.5 %) | 18 (21.4 %) | 77 (30.3 %) | |
Sex | |||||||
cat | |||||||
n | 2 | 1 | 86 | 84 | 84 | 254 | 0.141 |
Male | 2 | 2 | 33 (38.4 %) | 34 (40.5 %) | 44 (52.4 %) | 111 (43.7 %) | |
Female | 2 | 3 | 53 (61.6 %) | 50 (59.5 %) | 40 (47.6 %) | 143 (56.3 %) | |
Race (Origin) | |||||||
cat | |||||||
n | 3 | 1 | 86 | 84 | 84 | 254 | 0.648 |
Caucasian | 3 | 2 | 75 (87.2 %) | 72 (85.7 %) | 71 (84.5 %) | 218 (85.8 %) | |
African Descent | 3 | 3 | 8 ( 9.3 %) | 6 ( 7.1 %) | 9 (10.7 %) | 23 ( 9.1 %) | |
Hispanic | 3 | 4 | 3 ( 3.5 %) | 6 ( 7.1 %) | 3 ( 3.6 %) | 12 ( 4.7 %) | |
Other | 3 | 5 | 1 ( 1.2 %) | 1 ( 0.4 %) | |||
MMSE | |||||||
cont | |||||||
n | 4 | 1 | 86 | 84 | 84 | 254 | 0.595 |
Mean | 4 | 2 | 18.0 | 17.9 | 18.5 | 18.1 | |
SD | 4 | 3 | 4.27 | 4.22 | 4.16 | 4.21 | |
Median | 4 | 4 | 19.5 | 18.0 | 20.0 | 19.0 | |
Min | 4 | 5 | 10.0 | 10.0 | 10.0 | 10.0 | |
Max | 4 | 6 | 23.0 | 24.0 | 24.0 | 24.0 | |
Duration of disease | |||||||
cont | |||||||
n | 5 | 1 | 86 | 84 | 84 | 254 | 0.153 |
Mean | 5 | 2 | 42.6 | 48.7 | 40.5 | 43.9 | |
SD | 5 | 3 | 30.24 | 29.58 | 24.69 | 28.40 | |
Median | 5 | 4 | 35.3 | 40.2 | 36.0 | 36.2 | |
Min | 5 | 5 | 7.2 | 7.8 | 2.2 | 2.2 | |
Max | 5 | 6 | 183.1 | 130.8 | 135.0 | 183.1 | |
cat | |||||||
<12 months | 5 | 7 | 5 ( 5.8 %) | 3 ( 3.6 %) | 4 ( 4.8 %) | 12 ( 4.7 %) | 0.789 |
>=12 months | 5 | 8 | 81 (94.2 %) | 81 (96.4 %) | 80 (95.2 %) | 242 (95.3 %) | |
Years of education | |||||||
cont | |||||||
n | 6 | 1 | 86 | 84 | 84 | 254 | 0.388 |
Mean | 6 | 2 | 12.6 | 13.2 | 12.5 | 12.8 | |
SD | 6 | 3 | 2.95 | 4.15 | 2.92 | 3.38 | |
Median | 6 | 4 | 12.0 | 12.0 | 12.0 | 12.0 | |
Min | 6 | 5 | 6.0 | 3.0 | 6.0 | 3.0 | |
Max | 6 | 6 | 21.0 | 24.0 | 20.0 | 24.0 | |
Baseline weight(kg) | |||||||
cont | |||||||
n | 7 | 1 | 86 | 83 | 84 | 253 | 0.003 |
Mean | 7 | 2 | 62.8 | 67.3 | 70.0 | 66.6 | |
SD | 7 | 3 | 12.77 | 14.12 | 14.65 | 14.13 | |
Median | 7 | 4 | 60.5 | 64.9 | 69.2 | 66.7 | |
Min | 7 | 5 | 34.0 | 45.4 | 41.7 | 34.0 | |
Max | 7 | 6 | 86.2 | 106.1 | 108.0 | 108.0 | |
Baseline height(cm) | |||||||
cont | |||||||
n | 8 | 1 | 86 | 84 | 84 | 254 | 0.126 |
Mean | 8 | 2 | 162.6 | 163.4 | 165.8 | 163.9 | |
SD | 8 | 3 | 11.52 | 10.42 | 10.13 | 10.76 | |
Median | 8 | 4 | 162.6 | 162.6 | 165.1 | 162.8 | |
Min | 8 | 5 | 137.2 | 135.9 | 146.1 | 135.9 | |
Max | 8 | 6 | 185.4 | 195.6 | 190.5 | 195.6 | |
Baseline BMI | |||||||
cont | |||||||
n | 9 | 1 | 86 | 83 | 84 | 253 | 0.013 |
Mean | 9 | 2 | 23.6 | 25.1 | 25.3 | 24.7 | |
SD | 9 | 3 | 3.67 | 4.27 | 4.16 | 4.09 | |
Median | 9 | 4 | 23.4 | 24.3 | 24.8 | 24.2 | |
Min | 9 | 5 | 15.1 | 17.7 | 13.7 | 13.7 | |
Max | 9 | 6 | 33.3 | 40.1 | 34.5 | 40.1 | |
cat | |||||||
<25 | 9 | 7 | 59 (68.6 %) | 47 (56.0 %) | 44 (52.4 %) | 150 (59.1 %) | 0.233 |
25-<30 | 9 | 8 | 21 (24.4 %) | 27 (32.1 %) | 28 (33.3 %) | 76 (29.9 %) | |
>=30 | 9 | 9 | 6 ( 7.0 %) | 10 (11.9 %) | 12 (14.3 %) | 28 (11.0 %) |
Now that all the numbers look correct, we can drop the order columns
and the grp
column (note that while we do not want to
display the grp
column, it plays a role behind the scenes,
which will be addressed in the next step). To do this we use a
col_plan
which uses tidy-select
nomenclature
to drop/move columns.
tfrmt(
# specify columns in the data
group = c(rowlbl1,grp),
label = rowlbl2,
column = column,
param = param,
value = value,
sorting_cols = c(ord1, ord2),
# specify value formatting
body_plan = body_plan(
frmt_structure(group_val = ".default", label_val = ".default", frmt_combine("{n} {pct}",
n = frmt("xxx"),
pct = frmt_when("==100" ~ "",
"==0" ~ "",
TRUE ~ frmt("(xx.x %)")))),
frmt_structure(group_val = ".default", label_val = "n", frmt("xxx")),
frmt_structure(group_val = ".default", label_val = c("Mean", "Median", "Min","Max"), frmt("xxx.x")),
frmt_structure(group_val = ".default", label_val = "SD", frmt("xxx.xx")),
frmt_structure(group_val = ".default", label_val = ".default", p = frmt("")),
frmt_structure(group_val = ".default", label_val = c("n","<65 yrs","<12 months","<25"), p = frmt_when(">0.99" ~ ">0.99",
"<0.001" ~ "<0.001",
TRUE ~ frmt("x.xxx", missing = "")))
),
# remove extra cols
col_plan = col_plan(-grp,
-starts_with("ord") )) %>%
print_to_gt(data_demog) %>%
tab_options(
container.width = 900
)
Placebo | Xanomeline Low Dose | Xanomeline High Dose | Total | p-value | |
---|---|---|---|---|---|
Age (y) | |||||
n | 86 | 84 | 84 | 254 | 0.593 |
Mean | 75.2 | 75.7 | 74.4 | 75.1 | |
SD | 8.59 | 8.29 | 7.89 | 8.25 | |
Median | 76.0 | 77.5 | 76.0 | 77.0 | |
Min | 52.0 | 51.0 | 56.0 | 51.0 | |
Max | 89.0 | 88.0 | 88.0 | 89.0 | |
<65 yrs | 14 (16.3 %) | 8 ( 9.5 %) | 11 (13.1 %) | 33 (13.0 %) | 0.144 |
65-80 yrs | 42 (48.8 %) | 47 (56.0 %) | 55 (65.5 %) | 144 (56.7 %) | |
>80 yrs | 30 (34.9 %) | 29 (34.5 %) | 18 (21.4 %) | 77 (30.3 %) | |
Sex | |||||
n | 86 | 84 | 84 | 254 | 0.141 |
Male | 33 (38.4 %) | 34 (40.5 %) | 44 (52.4 %) | 111 (43.7 %) | |
Female | 53 (61.6 %) | 50 (59.5 %) | 40 (47.6 %) | 143 (56.3 %) | |
Race (Origin) | |||||
n | 86 | 84 | 84 | 254 | 0.648 |
Caucasian | 75 (87.2 %) | 72 (85.7 %) | 71 (84.5 %) | 218 (85.8 %) | |
African Descent | 8 ( 9.3 %) | 6 ( 7.1 %) | 9 (10.7 %) | 23 ( 9.1 %) | |
Hispanic | 3 ( 3.5 %) | 6 ( 7.1 %) | 3 ( 3.6 %) | 12 ( 4.7 %) | |
Other | 1 ( 1.2 %) | 1 ( 0.4 %) | |||
MMSE | |||||
n | 86 | 84 | 84 | 254 | 0.595 |
Mean | 18.0 | 17.9 | 18.5 | 18.1 | |
SD | 4.27 | 4.22 | 4.16 | 4.21 | |
Median | 19.5 | 18.0 | 20.0 | 19.0 | |
Min | 10.0 | 10.0 | 10.0 | 10.0 | |
Max | 23.0 | 24.0 | 24.0 | 24.0 | |
Duration of disease | |||||
n | 86 | 84 | 84 | 254 | 0.153 |
Mean | 42.6 | 48.7 | 40.5 | 43.9 | |
SD | 30.24 | 29.58 | 24.69 | 28.40 | |
Median | 35.3 | 40.2 | 36.0 | 36.2 | |
Min | 7.2 | 7.8 | 2.2 | 2.2 | |
Max | 183.1 | 130.8 | 135.0 | 183.1 | |
<12 months | 5 ( 5.8 %) | 3 ( 3.6 %) | 4 ( 4.8 %) | 12 ( 4.7 %) | 0.789 |
>=12 months | 81 (94.2 %) | 81 (96.4 %) | 80 (95.2 %) | 242 (95.3 %) | |
Years of education | |||||
n | 86 | 84 | 84 | 254 | 0.388 |
Mean | 12.6 | 13.2 | 12.5 | 12.8 | |
SD | 2.95 | 4.15 | 2.92 | 3.38 | |
Median | 12.0 | 12.0 | 12.0 | 12.0 | |
Min | 6.0 | 3.0 | 6.0 | 3.0 | |
Max | 21.0 | 24.0 | 20.0 | 24.0 | |
Baseline weight(kg) | |||||
n | 86 | 83 | 84 | 253 | 0.003 |
Mean | 62.8 | 67.3 | 70.0 | 66.6 | |
SD | 12.77 | 14.12 | 14.65 | 14.13 | |
Median | 60.5 | 64.9 | 69.2 | 66.7 | |
Min | 34.0 | 45.4 | 41.7 | 34.0 | |
Max | 86.2 | 106.1 | 108.0 | 108.0 | |
Baseline height(cm) | |||||
n | 86 | 84 | 84 | 254 | 0.126 |
Mean | 162.6 | 163.4 | 165.8 | 163.9 | |
SD | 11.52 | 10.42 | 10.13 | 10.76 | |
Median | 162.6 | 162.6 | 165.1 | 162.8 | |
Min | 137.2 | 135.9 | 146.1 | 135.9 | |
Max | 185.4 | 195.6 | 190.5 | 195.6 | |
Baseline BMI | |||||
n | 86 | 83 | 84 | 253 | 0.013 |
Mean | 23.6 | 25.1 | 25.3 | 24.7 | |
SD | 3.67 | 4.27 | 4.16 | 4.09 | |
Median | 23.4 | 24.3 | 24.8 | 24.2 | |
Min | 15.1 | 17.7 | 13.7 | 13.7 | |
Max | 33.3 | 40.1 | 34.5 | 40.1 | |
<25 | 59 (68.6 %) | 47 (56.0 %) | 44 (52.4 %) | 150 (59.1 %) | 0.233 |
25-<30 | 21 (24.4 %) | 27 (32.1 %) | 28 (33.3 %) | 76 (29.9 %) | |
>=30 | 6 ( 7.0 %) | 10 (11.9 %) | 12 (14.3 %) | 28 (11.0 %) |
Now this table looks just about right. There are two problems, (1)
alignment and (2) spacing between the continuous and categorical values.
To take care of the alignment we are going to add a
col_style_plan
which accepts a series of
col_style_structure
s. This allows columns to be aligned
differently if needed. For this table, we want all the columns to align
on either “.”, “,” or ” ” so our col_style_structure
looks
like
col_style_structure(align = c(".",","," "), col = vars(everything()))
.
After the alignment is sorted we can move on to the spacing. In order to
match the spacing of the mock we need to use the extra grp
column from our data. If we look at our data, we can see we want a space
any time either of the groups change.
data_demog %>%
distinct(rowlbl1,grp)
#> # A tibble: 12 × 2
#> # Groups: rowlbl1 [9]
#> rowlbl1 grp
#> <chr> <chr>
#> 1 "Age (y)" cont
#> 2 "Age (y)" cat
#> 3 "Sex" cat
#> 4 "Race (Origin)" cat
#> 5 "MMSE" cont
#> 6 "Duration of disease " cont
#> 7 "Duration of disease " cat
#> 8 "Years of education" cont
#> 9 "Baseline weight(kg)" cont
#> 10 "Baseline height(cm)" cont
#> 11 "Baseline BMI" cont
#> 12 "Baseline BMI" cat
This means that we can use a row_grp_plan
with just a
".default"
as the group value and it should handle all of
the spacing. In addition to the spacing, row_grp_plan
will
let us move the spanning group labels to a separate column by changing
the label_loc
to “column”.
tfrmt(
# specify columns in the data
group = c(rowlbl1,grp),
label = rowlbl2,
column = column,
param = param,
value = value,
sorting_cols = c(ord1, ord2),
# specify value formatting
body_plan = body_plan(
frmt_structure(group_val = ".default", label_val = ".default", frmt_combine("{n} {pct}",
n = frmt("xxx"),
pct = frmt_when("==100" ~ "",
"==0" ~ "",
TRUE ~ frmt("(xx.x %)")))),
frmt_structure(group_val = ".default", label_val = "n", frmt("xxx")),
frmt_structure(group_val = ".default", label_val = c("Mean", "Median", "Min","Max"), frmt("xxx.x")),
frmt_structure(group_val = ".default", label_val = "SD", frmt("xxx.xx")),
frmt_structure(group_val = ".default", label_val = ".default", p = frmt("")),
frmt_structure(group_val = ".default", label_val = c("n","<65 yrs","<12 months","<25"), p = frmt_when(">0.99" ~ ">0.99",
"<0.001" ~ "<0.001",
TRUE ~ frmt("x.xxx", missing = "")))
),
# remove extra cols
col_plan = col_plan(-grp,
-starts_with("ord") ),
# Specify column styling plan
col_style_plan = col_style_plan(
col_style_structure(align = c(".",","," "), col = c("Placebo", "Xanomeline Low Dose",
"Xanomeline High Dose", "Total", "p-value")),
col_style_structure(align = "left", col = c("rowlbl1","rowlbl2"))
),
# Specify row group plan
row_grp_plan = row_grp_plan(
row_grp_structure(group_val = ".default", element_block(post_space = " ")),
label_loc = element_row_grp_loc(location = "column")
)
) %>%
print_to_gt(data_demog) %>%
tab_options(
container.width = 900
)
Placebo | Xanomeline Low Dose | Xanomeline High Dose | Total | p-value | ||
---|---|---|---|---|---|---|
Age (y) | n | 86 | 84 | 84 | 254 | 0.593 |
Mean | 75.2 | 75.7 | 74.4 | 75.1 | ||
SD | 8.59 | 8.29 | 7.89 | 8.25 | ||
Median | 76.0 | 77.5 | 76.0 | 77.0 | ||
Min | 52.0 |