Example of table1
The data used for this example if from package boot
, called melanoma. The data consist of measurements made on patients with malignant melanoma.
The Grouping variable is patients status at the end of the study. 1 indicates that they had died from melanoma, 2 indicates that they were still alive and 3 indicates that they had died from causes unrelated to their melanoma.
melanoma1 <- melanoma
# Change status to factor
melanoma1$status <-
factor(melanoma1$status,
levels=c(2,1,3),
labels=c("Alive", # Reference
"Melanoma death",
"Non-melanoma death"))
# Change sex to factor and label them
melanoma1$sex <-
factor(melanoma1$sex, labels = c("Male",
"Female"))
# Change ulcer to factor and label them
melanoma1$ulcer <-
factor(melanoma1$ulcer, labels = c("Absent",
"Present"))
#Basic table 1
(table1.1 <- table1(~ sex + age + ulcer + thickness | status, data=melanoma1))
|
Alive (N=134) |
Melanoma death (N=57) |
Non-melanoma death (N=14) |
Overall (N=205) |
sex |
|
|
|
|
Male |
91 (67.9%) |
28 (49.1%) |
7 (50.0%) |
126 (61.5%) |
Female |
43 (32.1%) |
29 (50.9%) |
7 (50.0%) |
79 (38.5%) |
age |
|
|
|
|
Mean (SD) |
50.0 (15.9) |
55.1 (17.9) |
65.3 (10.9) |
52.5 (16.7) |
Median [Min, Max] |
52.0 [4.00, 84.0] |
56.0 [14.0, 95.0] |
65.0 [49.0, 86.0] |
54.0 [4.00, 95.0] |
ulcer |
|
|
|
|
Absent |
92 (68.7%) |
16 (28.1%) |
7 (50.0%) |
115 (56.1%) |
Present |
42 (31.3%) |
41 (71.9%) |
7 (50.0%) |
90 (43.9%) |
thickness |
|
|
|
|
Mean (SD) |
2.24 (2.33) |
4.31 (3.57) |
3.72 (3.63) |
2.92 (2.96) |
Median [Min, Max] |
1.36 [0.100, 12.9] |
3.54 [0.320, 17.4] |
2.26 [0.160, 12.6] |
1.94 [0.100, 17.4] |
To improve things, we can create factors with descriptive labels for the categorical variables (sex and ulcer), label each variable the way we want, and specify units for the continuous variables (age and thickness). We also specify that the overall column to be labeled “Total” and be positioned on the left, and add a caption and footnote.
melanoma2 <- melanoma1
#Label the variables name
label(melanoma2$sex) <- "Sex"
label(melanoma2$age) <- "Age"
label(melanoma2$ulcer) <- "Ulceration"
#I Use asterisk for footnote!
label(melanoma2$thickness) <- "Thickness *"
#Assign unit to age and thickness
units(melanoma2$age) <- "years"
units(melanoma2$thickness) <- "mm"
#create caption
caption <- "Descriptive statistics of patients characteristics by status"
#create footnote
footnote <- "* Also known as Breslow thickness"
#Create table1
table1(~ sex + age + ulcer + thickness | status, data=melanoma2,
overall=c(left="Total"), caption=caption, footnote=footnote)
Descriptive statistics of patients characteristics by status
|
Total (N=205) |
Alive (N=134) |
Melanoma death (N=57) |
Non-melanoma death (N=14) |
Sex |
|
|
|
|
Male |
126 (61.5%) |
91 (67.9%) |
28 (49.1%) |
7 (50.0%) |
Female |
79 (38.5%) |
43 (32.1%) |
29 (50.9%) |
7 (50.0%) |
Age (years) |
|
|
|
|
Mean (SD) |
52.5 (16.7) |
50.0 (15.9) |
55.1 (17.9) |
65.3 (10.9) |
Median [Min, Max] |
54.0 [4.00, 95.0] |
52.0 [4.00, 84.0] |
56.0 [14.0, 95.0] |
65.0 [49.0, 86.0] |
Ulceration |
|
|
|
|
Absent |
115 (56.1%) |
92 (68.7%) |
16 (28.1%) |
7 (50.0%) |
Present |
90 (43.9%) |
42 (31.3%) |
41 (71.9%) |
7 (50.0%) |
Thickness * (mm) |
|
|
|
|
Mean (SD) |
2.92 (2.96) |
2.24 (2.33) |
4.31 (3.57) |
3.72 (3.63) |
Median [Min, Max] |
1.94 [0.100, 17.4] |
1.36 [0.100, 12.9] |
3.54 [0.320, 17.4] |
2.26 [0.160, 12.6] |
Now we grouped together two “Death” strata (Melanoma and Non-melanoma) under a common heading.
#label the variables sex. age, ulcer, and Thickness
#Add groups label
labels <- list(
variables=list(sex="Sex",
age="Age (years)",
ulcer="Ulceration",
thickness="Thickness* (mm)"),
groups=list("", "", "Death"))
# Remove the word "death" from the labels, since it now appears above
levels(melanoma2$status) <- c("Alive", "Melanoma", "Non-melanoma")
#Set up our “strata”, or column, as a list of data.frame
strata <- c(list(Total=melanoma2), split(melanoma2, melanoma2$status))
#Create new table1
table1(strata, labels, groupspan=c(1, 1, 2), caption=caption, footnote=footnote)
Descriptive statistics of patients characteristics by status
|
|
|
Death |
|
Total (N=205) |
Alive (N=134) |
Melanoma (N=57) |
Non-melanoma (N=14) |
Sex |
|
|
|
|
Male |
126 (61.5%) |
91 (67.9%) |
28 (49.1%) |
7 (50.0%) |
Female |
79 (38.5%) |
43 (32.1%) |
29 (50.9%) |
7 (50.0%) |
Age (years) |
|
|
|
|
Mean (SD) |
52.5 (16.7) |
50.0 (15.9) |
55.1 (17.9) |
65.3 (10.9) |
Median [Min, Max] |
54.0 [4.00, 95.0] |
52.0 [4.00, 84.0] |
56.0 [14.0, 95.0] |
65.0 [49.0, 86.0] |
Ulceration |
|
|
|
|
Absent |
115 (56.1%) |
92 (68.7%) |
16 (28.1%) |
7 (50.0%) |
Present |
90 (43.9%) |
42 (31.3%) |
41 (71.9%) |
7 (50.0%) |
Thickness* (mm) |
|
|
|
|
Mean (SD) |
2.92 (2.96) |
2.24 (2.33) |
4.31 (3.57) |
3.72 (3.63) |
Median [Min, Max] |
1.94 [0.100, 17.4] |
1.36 [0.100, 12.9] |
3.54 [0.320, 17.4] |
2.26 [0.160, 12.6] |
You can see that Customizing in table1 in the last step is not very easy and need some extra work.
Converting to flextable
Now lets try to convert it to flextable
and customize it there!
#Converting to flextable
tab1.flex <- table1.1 |> t1flex()
#Print
tab1.flex
| Alive (N=134) | Melanoma death (N=57) | Non-melanoma death (N=14) | Overall (N=205) |
---|
sex |
|
|
|
|
Male | 91 (67.9%) | 28 (49.1%) | 7 (50.0%) | 126 (61.5%) |
Female | 43 (32.1%) | 29 (50.9%) | 7 (50.0%) | 79 (38.5%) |
age |
|
|
|
|
Mean (SD) | 50.0 (15.9) | 55.1 (17.9) | 65.3 (10.9) | 52.5 (16.7) |
Median [Min, Max] | 52.0 [4.00, 84.0] | 56.0 [14.0, 95.0] | 65.0 [49.0, 86.0] | 54.0 [4.00, 95.0] |
ulcer |
|
|
|
|
Absent | 92 (68.7%) | 16 (28.1%) | 7 (50.0%) | 115 (56.1%) |
Present | 42 (31.3%) | 41 (71.9%) | 7 (50.0%) | 90 (43.9%) |
thickness |
|
|
|
|
Mean (SD) | 2.24 (2.33) | 4.31 (3.57) | 3.72 (3.63) | 2.92 (2.96) |
Median [Min, Max] | 1.36 [0.100, 12.9] | 3.54 [0.320, 17.4] | 2.26 [0.160, 12.6] | 1.94 [0.100, 17.4] |
#Modify tab1.flex
tab1.flex |>
#add header row
add_header_row(
values = c("", "Death", ""), # Labels for the top header row
colwidths = c(2, 2, 1) # Number of columns spanned by each header
) |>
#Fist remove the borderline under death
hline(part = "header", i = 1, border = officer::fp_border(width = 0))|>
# Line over Melanoma and Non-melanoma
hline(part = "header", i = 1, border = officer::fp_border(width = 1.5), j = 3:4) |>
#Change lables for rows!
compose(i = 1, j = 1, as_paragraph(as_chunk("SEX"))) |>
compose(i = 4, j = 1, as_paragraph(as_chunk("AGE (years)"))) |>
compose(i = 7, j = 1, as_paragraph(as_chunk("Ulceration"))) |>
compose(i = 10, j = 1, as_paragraph(as_chunk("Thickness (mm)"))) |>
#Add Caption
set_caption(ft, caption = "Table 1: Descriptive statistics of patients characteristics by status") |>
##Add footnote
footnote( i = 10, j = 1,
ref_symbols = "a",
value = as_paragraph("Also known as Breslow thickness")
) |>
fontsize(i = 1, j =1 , size = 9, part = "footer")
Table 1: Descriptive statistics of patients characteristics by status
| Death |
|
---|
| Alive (N=134) | Melanoma death (N=57) | Non-melanoma death (N=14) | Overall (N=205) |
---|
SEX |
|
|
|
|
Male | 91 (67.9%) | 28 (49.1%) | 7 (50.0%) | 126 (61.5%) |
Female | 43 (32.1%) | 29 (50.9%) | 7 (50.0%) | 79 (38.5%) |
AGE (years) |
|
|
|
|
Mean (SD) | 50.0 (15.9) | 55.1 (17.9) | 65.3 (10.9) | 52.5 (16.7) |
Median [Min, Max] | 52.0 [4.00, 84.0] | 56.0 [14.0, 95.0] | 65.0 [49.0, 86.0] | 54.0 [4.00, 95.0] |
Ulceration |
|
|
|
|
Absent | 92 (68.7%) | 16 (28.1%) | 7 (50.0%) | 115 (56.1%) |
Present | 42 (31.3%) | 41 (71.9%) | 7 (50.0%) | 90 (43.9%) |
Thickness (mm)a |
|
|
|
|
Mean (SD) | 2.24 (2.33) | 4.31 (3.57) | 3.72 (3.63) | 2.92 (2.96) |
Median [Min, Max] | 1.36 [0.100, 12.9] | 3.54 [0.320, 17.4] | 2.26 [0.160, 12.6] | 1.94 [0.100, 17.4] |
aAlso known as Breslow thickness |
You may find it somewhat more line of the code but the steps are more straightforward and clear.
To learn more about package table1
see the link below:
Using the table1 Package to Create HTML Tables of Descriptive Statistics