47  table1绘制三线表

三线表/基线资料表作为临床医学论文中最常见的第一个三线表,几乎是100%必备技能!一般我们会通过Word和spss结合进行,在Word里面把三线表画好,然后把数据复制粘贴到Word里。

如果通过R语言的话那么实现方式非常多,前面给大家介绍了compareGroupstableone两个R包,今天再给大家介绍一下table1

47.1 安装

# 2种方式选择1个
install.packages("table1")

require(devtools)
devtools::install_github("benjaminrich/table1")

47.2 使用

为了方便比较,还是使用compareGroups包自带的regicor数据集。

为了说明这个软件包是如何工作的,我们从REGICOR研究中取了一部分数据。REGICOR是一个 对来自西班牙东北部的参与者进行的横断面研究,包括:人口统计学信息(年龄、性别、身高、体重、腰围等)、血脂特征(总胆固醇和胆固醇、甘油三酯等)、问卷调查信息(体育活动,生活质量,…)等。此外,心血管事件和 死亡信息来自医院和官方登记处。

library(compareGroups)
library(table1)
## 
## Attaching package: 'table1'
## The following objects are masked from 'package:base':
## 
##     units, units<-

data("regicor")
dim(regicor)
## [1] 2294   25
str(regicor)
## 'data.frame':    2294 obs. of  25 variables:
##  $ id      : num  2.26e+03 1.88e+03 3.00e+09 3.00e+09 3.00e+09 ...
##   ..- attr(*, "label")= Named chr "Individual id"
##   .. ..- attr(*, "names")= chr "id"
##  $ year    : Factor w/ 3 levels "1995","2000",..: 3 3 2 2 2 2 2 1 3 1 ...
##   ..- attr(*, "label")= Named chr "Recruitment year"
##   .. ..- attr(*, "names")= chr "year"
##  $ age     : int  70 56 37 69 70 40 66 53 43 70 ...
##   ..- attr(*, "label")= Named chr "Age"
##   .. ..- attr(*, "names")= chr "age"
##  $ sex     : Factor w/ 2 levels "Male","Female": 2 2 1 2 2 2 1 2 2 1 ...
##   ..- attr(*, "label")= chr "Sex"
##  $ smoker  : Factor w/ 3 levels "Never smoker",..: 1 1 2 1 NA 2 1 1 3 3 ...
##   ..- attr(*, "label")= Named chr "Smoking status"
##   .. ..- attr(*, "names")= chr "smoker"
##  $ sbp     : int  138 139 132 168 NA 108 120 132 95 142 ...
##   ..- attr(*, "label")= Named chr "Systolic blood pressure"
##   .. ..- attr(*, "names")= chr "sbp"
##  $ dbp     : int  75 89 82 97 NA 70 72 78 65 78 ...
##   ..- attr(*, "label")= Named chr "Diastolic blood pressure"
##   .. ..- attr(*, "names")= chr "dbp"
##  $ histhtn : Factor w/ 2 levels "Yes","No": 2 2 2 2 2 2 1 2 2 2 ...
##   ..- attr(*, "label")= Named chr "History of hypertension"
##   .. ..- attr(*, "names")= chr "histbp"
##  $ txhtn   : Factor w/ 2 levels "No","Yes": 1 1 1 1 1 1 2 1 1 1 ...
##   ..- attr(*, "label")= chr "Hypertension treatment"
##  $ chol    : num  294 220 245 168 NA NA 298 254 194 188 ...
##   ..- attr(*, "label")= Named chr "Total cholesterol"
##   .. ..- attr(*, "names")= chr "chol"
##  $ hdl     : num  57 50 59.8 53.2 NA ...
##   ..- attr(*, "label")= Named chr "HDL cholesterol"
##   .. ..- attr(*, "names")= chr "hdl"
##  $ triglyc : num  93 160 89 116 NA 94 71 NA 68 137 ...
##   ..- attr(*, "label")= Named chr "Triglycerides"
##   .. ..- attr(*, "names")= chr "triglyc"
##  $ ldl     : num  218.4 138 167.4 91.6 NA ...
##   ..- attr(*, "label")= Named chr "LDL cholesterol"
##   .. ..- attr(*, "names")= chr "ldl"
##  $ histchol: Factor w/ 2 levels "Yes","No": 2 2 2 2 NA 2 1 2 2 2 ...
##   ..- attr(*, "label")= chr "History of hyperchol."
##  $ txchol  : Factor w/ 2 levels "No","Yes": 1 1 1 1 NA 1 1 1 1 1 ...
##   ..- attr(*, "label")= Named chr "Cholesterol treatment"
##   .. ..- attr(*, "names")= chr "txchol"
##  $ height  : num  160 163 170 147 NA ...
##   ..- attr(*, "label")= Named chr "Height (cm)"
##   .. ..- attr(*, "names")= chr "height"
##  $ weight  : num  64 67 70 68 NA 43.5 79.2 45.8 53 62 ...
##   ..- attr(*, "label")= Named chr "Weight (Kg)"
##   .. ..- attr(*, "names")= chr "weight"
##  $ bmi     : num  25 25.2 24.2 31.5 NA ...
##   ..- attr(*, "label")= Named chr "Body mass index"
##   .. ..- attr(*, "names")= chr "bmi"
##  $ phyact  : num  304 160 553 522 NA ...
##   ..- attr(*, "label")= Named chr "Physical activity (Kcal/week)"
##   .. ..- attr(*, "names")= chr "phyact"
##  $ pcs     : num  54.5 58.2 43.4 54.3 NA ...
##   ..- attr(*, "label")= Named chr "Physical component"
##   .. ..- attr(*, "names")= chr "pcs"
##  $ mcs     : num  58.9 48 62.6 57.9 NA ...
##   ..- attr(*, "label")= chr "Mental component"
##  $ cv      : Factor w/ 2 levels "No","Yes": 1 1 1 1 NA 1 1 1 1 1 ...
##   ..- attr(*, "label")= chr "Cardiovascular event"
##  $ tocv    : num  1025 2757 1906 1055 NA ...
##   ..- attr(*, "label")= chr "Days to cardiovascular event or end of follow-up"
##  $ death   : Factor w/ 2 levels "No","Yes": 2 1 1 1 NA 1 2 1 1 1 ...
##   ..- attr(*, "label")= chr "Overall death"
##  $ todeath : num  1299.2 39.3 858.4 1833.1 NA ...
##   ..- attr(*, "label")= chr "Days to overall death or end of follow-up"

各个变量的信息如下:

Name Label Codes
id Individual id
year Recruitment year 1995; 2000; 2005
age Age
sex Sex Male; Female
smoker Smoking status Never smoker; Current or former < 1y; Former $\geq$ 1y
sbp Systolic blood pressure
dbp Diastolic blood pressure
histhtn History of hypertension Yes; No
txhtn Hypertension treatment No; Yes
chol Total cholesterol
hdl HDL cholesterol
triglyc Triglycerides
ldl LDL cholesterol
histchol History of hyperchol. Yes; No
txchol Cholesterol treatment No; Yes
height Height (cm)
weight Weight (Kg)
bmi Body mass index
phyact Physical activity (Kcal/week)
pcs Physical component
mcs Mental component
cv Cardiovascular event No; Yes
tocv Days to cardiovascular event or end of follow-up
death Overall death No; Yes
todeath Days to overall death or end of follow-up

大家在使用的时候还是要注意,要先把分类变量因子化!使用起来也是1行代码就可以出图了:

table1(~ . | year, data = regicor[,-1])
1995
(N=431)
2000
(N=786)
2005
(N=1077)
Overall
(N=2294)
Age
Mean (SD) 54.1 (11.7) 54.3 (11.2) 55.3 (10.6) 54.7 (11.0)
Median [Min, Max] 54.0 [35.0, 74.0] 54.0 [35.0, 74.0] 56.0 [35.0, 74.0] 55.0 [35.0, 74.0]
Sex
Male 206 (47.8%) 390 (49.6%) 505 (46.9%) 1101 (48.0%)
Female 225 (52.2%) 396 (50.4%) 572 (53.1%) 1193 (52.0%)
Smoking status
Never smoker 234 (54.3%) 414 (52.7%) 553 (51.3%) 1201 (52.4%)
Current or former < 1y 109 (25.3%) 267 (34.0%) 217 (20.1%) 593 (25.9%)
Former >= 1y 72 (16.7%) 77 (9.8%) 290 (26.9%) 439 (19.1%)
Missing 16 (3.7%) 28 (3.6%) 17 (1.6%) 61 (2.7%)
Systolic blood pressure
Mean (SD) 133 (19.2) 133 (21.3) 129 (19.8) 131 (20.3)
Median [Min, Max] 132 [92.0, 196] 132 [80.0, 212] 125 [88.0, 229] 129 [80.0, 229]
Missing 3 (0.7%) 11 (1.4%) 0 (0%) 14 (0.6%)
Diastolic blood pressure
Mean (SD) 77.0 (10.5) 80.8 (10.3) 79.9 (10.6) 79.7 (10.5)
Median [Min, Max] 78.0 [52.0, 108] 80.0 [50.0, 123] 79.0 [40.0, 121] 80.0 [40.0, 123]
Missing 3 (0.7%) 11 (1.4%) 0 (0%) 14 (0.6%)
History of hypertension
Yes 111 (25.8%) 233 (29.6%) 379 (35.2%) 723 (31.5%)
No 320 (74.2%) 553 (70.4%) 690 (64.1%) 1563 (68.1%)
Missing 0 (0%) 0 (0%) 8 (0.7%) 8 (0.3%)
Hypertension treatment
No 360 (83.5%) 659 (83.8%) 804 (74.7%) 1823 (79.5%)
Yes 71 (16.5%) 127 (16.2%) 230 (21.4%) 428 (18.7%)
Missing 0 (0%) 0 (0%) 43 (4.0%) 43 (1.9%)
Total cholesterol
Mean (SD) 225 (43.1) 224 (44.4) 213 (45.9) 219 (45.2)
Median [Min, Max] 225 [95.0, 361] 222 [113, 404] 209 [95.0, 488] 215 [95.0, 488]
Missing 28 (6.5%) 71 (9.0%) 2 (0.2%) 101 (4.4%)
HDL cholesterol
Mean (SD) 51.9 (14.5) 52.3 (15.6) 53.2 (14.2) 52.7 (14.7)
Median [Min, Max] 50.6 [24.5, 95.0] 49.7 [19.6, 103] 52.0 [20.0, 112] 51.0 [19.6, 112]
Missing 30 (7.0%) 38 (4.8%) 1 (0.1%) 69 (3.0%)
Triglycerides
Mean (SD) 114 (74.4) 114 (70.7) 117 (76.0) 116 (73.9)
Median [Min, Max] 94.0 [41.0, 882] 98.0 [25.0, 960] 98.0 [33.0, 744] 97.0 [25.0, 960]
Missing 28 (6.5%) 34 (4.3%) 1 (0.1%) 63 (2.7%)
LDL cholesterol
Mean (SD) 152 (38.4) 149 (38.6) 136 (39.7) 143 (39.7)
Median [Min, Max] 151 [36.3, 273] 147 [51.7, 300] 133 [36.8, 330] 141 [36.3, 330]
Missing 43 (10.0%) 98 (12.5%) 27 (2.5%) 168 (7.3%)
History of hyperchol.
Yes 97 (22.5%) 256 (32.6%) 356 (33.1%) 709 (30.9%)
No 334 (77.5%) 515 (65.5%) 715 (66.4%) 1564 (68.2%)
Missing 0 (0%) 15 (1.9%) 6 (0.6%) 21 (0.9%)
Cholesterol treatment
No 403 (93.5%) 705 (89.7%) 903 (83.8%) 2011 (87.7%)
Yes 28 (6.5%) 68 (8.7%) 132 (12.3%) 228 (9.9%)
Missing 0 (0%) 13 (1.7%) 42 (3.9%) 55 (2.4%)
Height (cm)
Mean (SD) 163 (9.21) 162 (9.39) 163 (9.05) 163 (9.22)
Median [Min, Max] 163 [143, 192] 162 [139, 190] 163 [137, 199] 163 [137, 199]
Missing 8 (1.9%) 15 (1.9%) 12 (1.1%) 35 (1.5%)
Weight (Kg)
Mean (SD) 72.3 (12.6) 73.8 (14.0) 73.6 (13.9) 73.4 (13.7)
Median [Min, Max] 72.0 [41.2, 127] 73.0 [43.5, 118] 73.0 [42.0, 125] 73.0 [41.2, 127]
Missing 8 (1.9%) 15 (1.9%) 12 (1.1%) 35 (1.5%)
Body mass index
Mean (SD) 27.0 (4.15) 28.1 (4.62) 27.6 (4.63) 27.6 (4.56)
Median [Min, Max] 26.5 [17.2, 43.7] 27.6 [17.4, 48.2] 27.2 [17.1, 48.2] 27.2 [17.1, 48.2]
Missing 8 (1.9%) 15 (1.9%) 12 (1.1%) 35 (1.5%)
Physical activity (Kcal/week)
Mean (SD) 491 (419) 422 (377) 351 (378) 399 (388)
Median [Min, Max] 390 [1.00, 3430] 347 [0, 5080] 262 [0, 4230] 304 [0, 5080]
Missing 64 (14.8%) 22 (2.8%) 2 (0.2%) 88 (3.8%)
Physical component
Mean (SD) 49.3 (8.08) 49.0 (9.63) 50.1 (8.91) 49.6 (9.01)
Median [Min, Max] 51.7 [18.6, 66.2] 51.9 [13.9, 67.0] 53.1 [17.9, 67.1] 52.3 [13.9, 67.1]
Missing 34 (7.9%) 123 (15.6%) 83 (7.7%) 240 (10.5%)
Mental component
Mean (SD) 49.2 (11.3) 48.9 (11.0) 46.9 (10.8) 48.0 (11.0)
Median [Min, Max] 52.3 [3.42, 69.9] 52.8 [10.2, 69.4] 49.7 [7.62, 67.6] 51.3 [3.42, 69.9]
Missing 34 (7.9%) 123 (15.6%) 83 (7.7%) 240 (10.5%)
Cardiovascular event
No 388 (90.0%) 706 (89.8%) 977 (90.7%) 2071 (90.3%)
Yes 10 (2.3%) 35 (4.5%) 47 (4.4%) 92 (4.0%)
Missing 33 (7.7%) 45 (5.7%) 53 (4.9%) 131 (5.7%)
Days to cardiovascular event or end of follow-up
Mean (SD) 1780 (1100) 1690 (1080) 1790 (1070) 1750 (1080)
Median [Min, Max] 1730 [0.260, 3650] 1620 [0.115, 3640] 1770 [2.65, 3650] 1720 [0.115, 3650]
Missing 33 (7.7%) 45 (5.7%) 53 (4.9%) 131 (5.7%)
Overall death
No 369 (85.6%) 657 (83.6%) 949 (88.1%) 1975 (86.1%)
Yes 18 (4.2%) 81 (10.3%) 74 (6.9%) 173 (7.5%)
Missing 44 (10.2%) 48 (6.1%) 54 (5.0%) 146 (6.4%)
Days to overall death or end of follow-up
Mean (SD) 1710 (1040) 1670 (1050) 1760 (1050) 1720 (1050)
Median [Min, Max] 1560 [0.220, 3640] 1610 [0.897, 3650] 1730 [0.889, 3650] 1670 [0.220, 3650]
Missing 44 (10.2%) 48 (6.1%) 54 (5.0%) 146 (6.4%)

是不是很简单,把需要分组的变量放在|后面即可。

结果是html形式的,可以直接复制粘贴到Word里面,连续性变量默认给出了两种表示方式!

47.3 美化

先给大家展示下复杂表头的制作格式,其实非常简单,就是用*即可。

table1(~  . | year*sex, data = regicor[,-1],overall = F) # 不展示overall
1995
2000
2005
Male
(N=206)
Female
(N=225)
Male
(N=390)
Female
(N=396)
Male
(N=505)
Female
(N=572)
Age
Mean (SD) 54.1 (11.8) 54.1 (11.7) 54.3 (11.2) 54.4 (11.2) 55.4 (10.7) 55.2 (10.6)
Median [Min, Max] 53.0 [35.0, 74.0] 54.0 [35.0, 74.0] 54.0 [35.0, 74.0] 54.0 [35.0, 74.0] 55.0 [35.0, 74.0] 56.0 [35.0, 74.0]
Smoking status
Never smoker 52 (25.2%) 182 (80.9%) 112 (28.7%) 302 (76.3%) 137 (27.1%) 416 (72.7%)
Current or former < 1y 77 (37.4%) 32 (14.2%) 199 (51.0%) 68 (17.2%) 134 (26.5%) 83 (14.5%)
Former >= 1y 67 (32.5%) 5 (2.2%) 66 (16.9%) 11 (2.8%) 227 (45.0%) 63 (11.0%)
Missing 10 (4.9%) 6 (2.7%) 13 (3.3%) 15 (3.8%) 7 (1.4%) 10 (1.7%)
Systolic blood pressure
Mean (SD) 134 (18.4) 132 (19.8) 137 (19.3) 129 (22.6) 132 (18.7) 127 (20.5)
Median [Min, Max] 132 [92.0, 184] 132 [92.0, 196] 134 [90.0, 212] 124 [80.0, 206] 129 [93.0, 200] 122 [88.0, 229]
Missing 0 (0%) 3 (1.3%) 3 (0.8%) 8 (2.0%) 0 (0%) 0 (0%)
Diastolic blood pressure
Mean (SD) 79.0 (9.27) 75.2 (11.3) 83.0 (9.54) 78.6 (10.6) 81.7 (10.8) 78.3 (10.0)
Median [Min, Max] 78.0 [54.0, 108] 74.0 [52.0, 102] 82.0 [60.0, 123] 80.0 [50.0, 112] 81.0 [40.0, 121] 78.0 [47.0, 111]
Missing 0 (0%) 3 (1.3%) 3 (0.8%) 8 (2.0%) 0 (0%) 0 (0%)
History of hypertension
Yes 50 (24.3%) 61 (27.1%) 110 (28.2%) 123 (31.1%) 181 (35.8%) 198 (34.6%)
No 156 (75.7%) 164 (72.9%) 280 (71.8%) 273 (68.9%) 319 (63.2%) 371 (64.9%)
Missing 0 (0%) 0 (0%) 0 (0%) 0 (0%) 5 (1.0%) 3 (0.5%)
Hypertension treatment
No 175 (85.0%) 185 (82.2%) 342 (87.7%) 317 (80.1%) 372 (73.7%) 432 (75.5%)
Yes 31 (15.0%) 40 (17.8%) 48 (12.3%) 79 (19.9%) 110 (21.8%) 120 (21.0%)
Missing 0 (0%) 0 (0%) 0 (0%) 0 (0%) 23 (4.6%) 20 (3.5%)
Total cholesterol
Mean (SD) 224 (43.9) 226 (42.4) 224 (43.9) 224 (44.9) 210 (40.3) 216 (50.3)
Median [Min, Max] 224 [101, 346] 227 [95.0, 361] 226 [122, 404] 220 [113, 386] 207 [95.0, 369] 211 [109, 488]
Missing 10 (4.9%) 18 (8.0%) 37 (9.5%) 34 (8.6%) 0 (0%) 2 (0.3%)
HDL cholesterol
Mean (SD) 46.5 (13.1) 56.9 (13.9) 47.3 (12.6) 57.4 (16.7) 48.1 (12.4) 57.8 (14.2)
Median [Min, Max] 45.3 [24.5, 95.0] 56.6 [28.6, 92.6] 45.7 [19.6, 94.2] 56.8 [20.1, 103] 47.0 [20.0, 97.0] 57.0 [21.0, 112]
Missing 11 (5.3%) 19 (8.4%) 15 (3.8%) 23 (5.8%) 0 (0%) 1 (0.2%)
Triglycerides
Mean (SD) 131 (91.5) 97.8 (47.9) 128 (81.1) 99.7 (55.1) 132 (90.3) 104 (57.6)
Median [Min, Max] 110 [43.0, 882] 86.0 [41.0, 364] 113 [25.0, 960] 87.0 [31.0, 604] 108 [33.0, 744] 90.0 [33.0, 521]
Missing 9 (4.4%) 19 (8.4%) 17 (4.4%) 17 (4.3%) 0 (0%) 1 (0.2%)
LDL cholesterol
Mean (SD) 153 (39.6) 150 (37.3) 152 (39.1) 146 (38.0) 137 (36.0) 136 (42.6)
Median [Min, Max] 153 [36.3, 266] 148 [38.6, 273] 150 [51.7, 300] 142 [57.7, 290] 132 [38.2, 289] 133 [36.8, 330]
Missing 18 (8.7%) 25 (11.1%) 52 (13.3%) 46 (11.6%) 21 (4.2%) 6 (1.0%)
History of hyperchol.
Yes 48 (23.3%) 49 (21.8%) 138 (35.4%) 118 (29.8%) 167 (33.1%) 189 (33.0%)
No 158 (76.7%) 176 (78.2%) 247 (63.3%) 268 (67.7%) 336 (66.5%) 379 (66.3%)
Missing 0 (0%) 0 (0%) 5 (1.3%) 10 (2.5%) 2 (0.4%) 4 (0.7%)
Cholesterol treatment
No 189 (91.7%) 214 (95.1%) 348 (89.2%) 357 (90.2%) 425 (84.2%) 478 (83.6%)
Yes 17 (8.3%) 11 (4.9%) 38 (9.7%) 30 (7.6%) 59 (11.7%) 73 (12.8%)
Missing 0 (0%) 0 (0%) 4 (1.0%) 9 (2.3%) 21 (4.2%) 21 (3.7%)
Height (cm)
Mean (SD) 170 (7.34) 158 (6.31) 168 (7.17) 156 (6.50) 170 (7.43) 158 (6.24)
Median [Min, Max] 170 [148, 192] 158 [143, 178] 168 [144, 190] 155 [139, 176] 170 [148, 199] 157 [137, 180]
Missing 2 (1.0%) 6 (2.7%) 5 (1.3%) 10 (2.5%) 4 (0.8%) 8 (1.4%)
Weight (Kg)
Mean (SD) 77.6 (11.7) 67.3 (11.3) 80.1 (12.3) 67.6 (12.6) 80.2 (11.6) 67.7 (13.0)
Median [Min, Max] 77.3 [41.2, 127] 66.0 [43.2, 98.6] 79.2 [50.0, 117] 66.0 [43.5, 118] 79.0 [43.0, 122] 66.0 [42.0, 125]
Missing 2 (1.0%) 6 (2.7%) 5 (1.3%) 10 (2.5%) 4 (0.8%) 8 (1.4%)
Body mass index
Mean (SD) 26.9 (3.64) 27.2 (4.57) 28.2 (3.89) 28.0 (5.25) 27.9 (3.58) 27.3 (5.39)
Median [Min, Max] 26.5 [18.5, 39.6] 26.4 [17.2, 43.7] 28.0 [18.4, 40.5] 27.0 [17.4, 48.2] 27.7 [18.1, 42.6] 26.7 [17.1, 48.2]
Missing 2 (1.0%) 6 (2.7%) 5 (1.3%) 10 (2.5%) 4 (0.8%) 8 (1.4%)
Physical activity (Kcal/week)
Mean (SD) 422 (418) 553 (412) 356 (362) 486 (382) 439 (467) 273 (253)
Median [Min, Max] 291 [1.00, 3240] 479 [18.0, 3430] 264 [0, 4220] 417 [0, 5080] 317 [0, 4230] 222 [0, 1960]
Missing 31 (15.0%) 33 (14.7%) 10 (2.6%) 12 (3.0%) 0 (0%) 2 (0.3%)
Physical component
Mean (SD) 50.1 (6.71) 48.6 (9.16) 50.9 (8.58) 47.1 (10.2) 51.5 (8.07) 48.9 (9.45)
Median [Min, Max] 51.9 [23.3, 65.9] 51.2 [18.6, 66.2] 54.3 [13.9, 67.0] 49.7 [18.3, 65.1] 54.5 [18.2, 67.1] 51.6 [17.9, 64.6]
Missing 12 (5.8%) 22 (9.8%) 57 (14.6%) 66 (16.7%) 30 (5.9%) 53 (9.3%)
Mental component
Mean (SD) 52.1 (9.67) 46.5 (12.2) 50.9 (10.2) 46.9 (11.3) 49.2 (9.67) 44.7 (11.2)
Median [Min, Max] 54.4 [3.42, 66.4] 49.4 [9.93, 69.9] 54.5 [14.5, 65.4] 49.6 [10.2, 69.4] 51.9 [7.62, 67.6] 47.3 [12.5, 65.1]
Missing 12 (5.8%) 22 (9.8%) 57 (14.6%) 66 (16.7%) 30 (5.9%) 53 (9.3%)
Cardiovascular event
No 190 (92.2%) 198 (88.0%) 345 (88.5%) 361 (91.2%) 461 (91.3%) 516 (90.2%)
Yes 6 (2.9%) 4 (1.8%) 21 (5.4%) 14 (3.5%) 19 (3.8%) 28 (4.9%)
Missing 10 (4.9%) 23 (10.2%) 24 (6.2%) 21 (5.3%) 25 (5.0%) 28 (4.9%)
Days to cardiovascular event or end of follow-up
Mean (SD) 1720 (1130) 1850 (1070) 1650 (1080) 1720 (1080) 1830 (1060) 1760 (1080)
Median [Min, Max] 1620 [0.260, 3640] 1830 [26.4, 3650] 1610 [0.115, 3640] 1620 [0.279, 3630] 1820 [2.65, 3640] 1750 [7.22, 3650]
Missing 10 (4.9%) 23 (10.2%) 24 (6.2%) 21 (5.3%) 25 (5.0%) 28 (4.9%)
Overall death
No 174 (84.5%) 195 (86.7%) 321 (82.3%) 336 (84.8%) 448 (88.7%) 501 (87.6%)
Yes 12 (5.8%) 6 (2.7%) 46 (11.8%) 35 (8.8%) 29 (5.7%) 45 (7.9%)
Missing 20 (9.7%) 24 (10.7%) 23 (5.9%) 25 (6.3%) 28 (5.5%) 26 (4.5%)
Days to overall death or end of follow-up
Mean (SD) 1690 (1030) 1740 (1050) 1660 (1030) 1680 (1070) 1680 (1030) 1820 (1070)
Median [Min, Max] 1560 [0.220, 3640] 1590 [47.7, 3640] 1610 [0.897, 3620] 1620 [1.78, 3650] 1690 [0.889, 3630] 1810 [1.05, 3650]
Missing 20 (9.7%) 24 (10.7%) 23 (5.9%) 25 (6.3%) 28 (5.5%) 26 (4.5%)

还可以制作更加复杂的表头,比如把2000年和2005年放在同一个表头下,1995年单独放。

这种情况,就需要先进行一点自定义设置了。

labels <- list(
  
  # 先设置需要展示的变量,并设置下展示的名字
  variables = list(sex="Sex",age="Age(year)",smoker="Smoking status",
                   sbp="Systolic blood pressure",dbp="Diastolic blood pressure",
                   histhtn="History of hypertension",
                   txhtn="Hypertension treatment",chol="Total cholesterol",
                   hdl="HDL cholesterol",triglyc="Triglycerides",
                   ldl="LDL cholesterol"
               ),
  # 设置分组
  groups = list("","","2000年以后")
  )

# 因子化分组变量,但regicor数据集已经因子化了,这里不用也可以
levels(regicor$year) <- c("1995","2000","2005")

然后再设置一下分组变量

strata <- c(list(Total=regicor[,-1]),split(regicor,regicor$year))

然后就能愉快的显示了,是不是很强?

table1(strata, labels, groupspan = c(1,1,2),
       render.continuous=c(.="Mean ± SD") # 设置连续性变量的显示方式
       )
2000年以后
Total
(N=2294)
1995
(N=431)
2000
(N=786)
2005
(N=1077)
Sex
Male 1101 (48.0%) 206 (47.8%) 390 (49.6%) 505 (46.9%)
Female 1193 (52.0%) 225 (52.2%) 396 (50.4%) 572 (53.1%)
Age(year)
Mean ± SD 54.7 ± 11.0 54.1 ± 11.7 54.3 ± 11.2 55.3 ± 10.6
Smoking status
Never smoker 1201 (52.4%) 234 (54.3%) 414 (52.7%) 553 (51.3%)
Current or former < 1y 593 (25.9%) 109 (25.3%) 267 (34.0%) 217 (20.1%)
Former >= 1y 439 (19.1%) 72 (16.7%) 77 (9.8%) 290 (26.9%)
Missing 61 (2.7%) 16 (3.7%) 28 (3.6%) 17 (1.6%)
Systolic blood pressure
Mean ± SD 131 ± 20.3 133 ± 19.2 133 ± 21.3 129 ± 19.8
Missing 14 (0.6%) 3 (0.7%) 11 (1.4%) 0 (0%)
Diastolic blood pressure
Mean ± SD 79.7 ± 10.5 77.0 ± 10.5 80.8 ± 10.3 79.9 ± 10.6
Missing 14 (0.6%) 3 (0.7%) 11 (1.4%) 0 (0%)
History of hypertension
Yes 723 (31.5%) 111 (25.8%) 233 (29.6%) 379 (35.2%)
No 1563 (68.1%) 320 (74.2%) 553 (70.4%) 690 (64.1%)
Missing 8 (0.3%) 0 (0%) 0 (0%) 8 (0.7%)
Hypertension treatment
No 1823 (79.5%) 360 (83.5%) 659 (83.8%) 804 (74.7%)
Yes 428 (18.7%) 71 (16.5%) 127 (16.2%) 230 (21.4%)
Missing 43 (1.9%) 0 (0%) 0 (0%) 43 (4.0%)
Total cholesterol
Mean ± SD 219 ± 45.2 225 ± 43.1 224 ± 44.4 213 ± 45.9
Missing 101 (4.4%) 28 (6.5%) 71 (9.0%) 2 (0.2%)
HDL cholesterol
Mean ± SD 52.7 ± 14.7 51.9 ± 14.5 52.3 ± 15.6 53.2 ± 14.2
Missing 69 (3.0%) 30 (7.0%) 38 (4.8%) 1 (0.1%)
Triglycerides
Mean ± SD 116 ± 73.9 114 ± 74.4 114 ± 70.7 117 ± 76.0
Missing 63 (2.7%) 28 (6.5%) 34 (4.3%) 1 (0.1%)
LDL cholesterol
Mean ± SD 143 ± 39.7 152 ± 38.4 149 ± 38.6 136 ± 39.7
Missing 168 (7.3%) 43 (10.0%) 98 (12.5%) 27 (2.5%)

是不是很好看?基本符合要求了!

但是如果有的数值型变量不符合正态分布怎么办?

可以通过自定义函数解决。

# 自定义你的变量要如何显示
rndr <- function(x, name, ...) {
  # 分类变量就用默认方法
  if (!is.numeric(x)) return(render.categorical.default(x))
  
  # 连续型变量自定义一下
  what <- switch(name,
                 age = "Mean (SD)",
                 sbp = "Mean (SD)",
                 dbp = "Mean ± SD",
                 chol = "Median [IQR]", 
                 hdl  = "Median [IQR]",
                 triglyc = "Median [Min, Max]",
                 ldl = "Median [IQR]"
                 )
  parse.abbrev.render.code(c("", what))(x)
}

这样就能愉快的显示了,不过上面那段代码还是太复杂了~

table1(strata, labels, groupspan = c(1,1,2),
       render=rndr
       )
2000年以后
Total
(N=2294)
1995
(N=431)
2000
(N=786)
2005
(N=1077)
Sex
Male 1101 (48.0%) 206 (47.8%) 390 (49.6%) 505 (46.9%)
Female 1193 (52.0%) 225 (52.2%) 396 (50.4%) 572 (53.1%)
Age(year)
Mean (SD) 54.7 (11.0) 54.1 (11.7) 54.3 (11.2) 55.3 (10.6)
Smoking status
Never smoker 1201 (52.4%) 234 (54.3%) 414 (52.7%) 553 (51.3%)
Current or former < 1y 593 (25.9%) 109 (25.3%) 267 (34.0%) 217 (20.1%)
Former >= 1y 439 (19.1%) 72 (16.7%) 77 (9.8%) 290 (26.9%)
Systolic blood pressure
Mean (SD) 131 (20.3) 133 (19.2) 133 (21.3) 129 (19.8)
Diastolic blood pressure
Mean ± SD 79.7 ± 10.5 77.0 ± 10.5 80.8 ± 10.3 79.9 ± 10.6
History of hypertension
Yes 723 (31.5%) 111 (25.8%) 233 (29.6%) 379 (35.2%)
No 1563 (68.1%) 320 (74.2%) 553 (70.4%) 690 (64.1%)
Hypertension treatment
No 1823 (79.5%) 360 (83.5%) 659 (83.8%) 804 (74.7%)
Yes 428 (18.7%) 71 (16.5%) 127 (16.2%) 230 (21.4%)
Total cholesterol
Median [IQR] 215 [56.0] 225 [58.0] 222 [57.0] 209 [54.0]
HDL cholesterol
Median [IQR] 51.0 [19.4] 50.6 [20.0] 49.7 [21.3] 52.0 [18.0]
Triglycerides
Median [Min, Max] 97.0 [25.0, 960] 94.0 [41.0, 882] 98.0 [25.0, 960] 98.0 [33.0, 744]
LDL cholesterol
Median [IQR] 141 [52.4] 151 [48.8] 147 [53.4] 133 [48.8]

还有很多自带的样式可以使用:

table1(strata, labels, groupspan = c(1,1,2),
       render=rndr, topclass="Rtable1-zebra"
       )
2000年以后
Total
(N=2294)
1995
(N=431)
2000
(N=786)
2005
(N=1077)
Sex
Male 1101 (48.0%) 206 (47.8%) 390 (49.6%) 505 (46.9%)
Female 1193 (52.0%) 225 (52.2%) 396 (50.4%) 572 (53.1%)
Age(year)
Mean (SD) 54.7 (11.0) 54.1 (11.7) 54.3 (11.2) 55.3 (10.6)
Smoking status
Never smoker 1201 (52.4%) 234 (54.3%) 414 (52.7%) 553 (51.3%)
Current or former < 1y 593 (25.9%) 109 (25.3%) 267 (34.0%) 217 (20.1%)
Former >= 1y 439 (19.1%) 72 (16.7%) 77 (9.8%) 290 (26.9%)
Systolic blood pressure
Mean (SD) 131 (20.3) 133 (19.2) 133 (21.3) 129 (19.8)
Diastolic blood pressure
Mean ± SD 79.7 ± 10.5 77.0 ± 10.5 80.8 ± 10.3 79.9 ± 10.6
History of hypertension
Yes 723 (31.5%) 111 (25.8%) 233 (29.6%) 379 (35.2%)
No 1563 (68.1%) 320 (74.2%) 553 (70.4%) 690 (64.1%)
Hypertension treatment
No 1823 (79.5%) 360 (83.5%) 659 (83.8%) 804 (74.7%)
Yes 428 (18.7%) 71 (16.5%) 127 (16.2%) 230 (21.4%)
Total cholesterol
Median [IQR] 215 [56.0] 225 [58.0] 222 [57.0] 209 [54.0]
HDL cholesterol
Median [IQR] 51.0 [19.4] 50.6 [20.0] 49.7 [21.3] 52.0 [18.0]
Triglycerides
Median [Min, Max] 97.0 [25.0, 960] 94.0 [41.0, 882] 98.0 [25.0, 960] 98.0 [33.0, 744]
LDL cholesterol
Median [IQR] 141 [52.4] 151 [48.8] 147 [53.4] 133 [48.8]

47.4 添加P值

添加P值可以通过自定义函数解决,这样做的好处是可以自定义使用的方法,不好的一点是太复杂了,小白不友好,不符合简单快捷的原则。

# 构建函数,对不同类型自定义统计方法
pvalue <- function(x, ...) {
    # Construct vectors of data y, and groups (strata) g
    y <- unlist(x)
    g <- factor(rep(1:length(x), times=sapply(x, length)))
    if (is.numeric(y)) {
        # 连续型变量用方差分析
        p <- oneway.test(y ~ g)$p.value
    } else {
        # 分类变量采用卡方检验
        p <- chisq.test(table(y, g))$p.value
    }
    # 设置p值的表示形式
    # The initial empty string places the output on the line below the variable label.
    c("", sub("<", "&lt;", format.pval(p, digits=3, eps=0.001)))
}

但是添加了P值就不能使用自定义的表头了,果然是鱼与熊掌不可兼得啊

table1(~ . | year, data = regicor[,-1], overall = F,
       extra.col=list(`P-value`=pvalue),
       render.continuous=c(.="Mean ± SD")
       )
1995
(N=431)
2000
(N=786)
2005
(N=1077)
P-value
Age
Mean ± SD 54.1 ± 11.7 54.3 ± 11.2 55.3 ± 10.6 0.0786
Sex
Male 206 (47.8%) 390 (49.6%) 505 (46.9%) 0.506
Female 225 (52.2%) 396 (50.4%) 572 (53.1%)
Smoking status
Never smoker 234 (54.3%) 414 (52.7%) 553 (51.3%) <0.001
Current or former < 1y 109 (25.3%) 267 (34.0%) 217 (20.1%)
Former >= 1y 72 (16.7%) 77 (9.8%) 290 (26.9%)
Missing 16 (3.7%) 28 (3.6%) 17 (1.6%)
Systolic blood pressure
Mean ± SD 133 ± 19.2 133 ± 21.3 129 ± 19.8 <0.001
Missing 3 (0.7%) 11 (1.4%) 0 (0%)
Diastolic blood pressure
Mean ± SD 77.0 ± 10.5 80.8 ± 10.3 79.9 ± 10.6 <0.001
Missing 3 (0.7%) 11 (1.4%) 0 (0%)
History of hypertension
Yes 111 (25.8%) 233 (29.6%) 379 (35.2%) <0.001
No 320 (74.2%) 553 (70.4%) 690 (64.1%)
Missing 0 (0%) 0 (0%) 8 (0.7%)
Hypertension treatment
No 360 (83.5%) 659 (83.8%) 804 (74.7%) 0.00152
Yes 71 (16.5%) 127 (16.2%) 230 (21.4%)
Missing 0 (0%) 0 (0%) 43 (4.0%)
Total cholesterol
Mean ± SD 225 ± 43.1 224 ± 44.4 213 ± 45.9 <0.001
Missing 28 (6.5%) 71 (9.0%) 2 (0.2%)
HDL cholesterol
Mean ± SD 51.9 ± 14.5 52.3 ± 15.6 53.2 ± 14.2 0.198
Missing 30 (7.0%) 38 (4.8%) 1 (0.1%)
Triglycerides
Mean ± SD 114 ± 74.4 114 ± 70.7 117 ± 76.0 0.583
Missing 28 (6.5%) 34 (4.3%) 1 (0.1%)
LDL cholesterol
Mean ± SD 152 ± 38.4 149 ± 38.6 136 ± 39.7 <0.001
Missing 43 (10.0%) 98 (12.5%) 27 (2.5%)
History of hyperchol.
Yes 97 (22.5%) 256 (32.6%) 356 (33.1%) <0.001
No 334 (77.5%) 515 (65.5%) 715 (66.4%)
Missing 0 (0%) 15 (1.9%) 6 (0.6%)
Cholesterol treatment
No 403 (93.5%) 705 (89.7%) 903 (83.8%) <0.001
Yes 28 (6.5%) 68 (8.7%) 132 (12.3%)
Missing 0 (0%) 13 (1.7%) 42 (3.9%)
Height (cm)
Mean ± SD 163 ± 9.21 162 ± 9.39 163 ± 9.05 0.00368
Missing 8 (1.9%) 15 (1.9%) 12 (1.1%)
Weight (Kg)
Mean ± SD 72.3 ± 12.6 73.8 ± 14.0 73.6 ± 13.9 0.12
Missing 8 (1.9%) 15 (1.9%) 12 (1.1%)
Body mass index
Mean ± SD 27.0 ± 4.15 28.1 ± 4.62 27.6 ± 4.63 <0.001
Missing 8 (1.9%) 15 (1.9%) 12 (1.1%)
Physical activity (Kcal/week)
Mean ± SD 491 ± 419 422 ± 377 351 ± 378 <0.001
Missing 64 (14.8%) 22 (2.8%) 2 (0.2%)
Physical component
Mean ± SD 49.3 ± 8.08 49.0 ± 9.63 50.1 ± 8.91 0.0366
Missing 34 (7.9%) 123 (15.6%) 83 (7.7%)
Mental component
Mean ± SD 49.2 ± 11.3 48.9 ± 11.0 46.9 ± 10.8 <0.001
Missing 34 (7.9%) 123 (15.6%) 83 (7.7%)
Cardiovascular event
No 388 (90.0%) 706 (89.8%) 977 (90.7%) 0.161
Yes 10 (2.3%) 35 (4.5%) 47 (4.4%)
Missing 33 (7.7%) 45 (5.7%) 53 (4.9%)
Days to cardiovascular event or end of follow-up
Mean ± SD 1780 ± 1100 1690 ± 1080 1790 ± 1070 0.0989
Missing 33 (7.7%) 45 (5.7%) 53 (4.9%)
Overall death
No 369 (85.6%) 657 (83.6%) 949 (88.1%) <0.001
Yes 18 (4.2%) 81 (10.3%) 74 (6.9%)
Missing 44 (10.2%) 48 (6.1%) 54 (5.0%)
Days to overall death or end of follow-up
Mean ± SD 1710 ± 1040 1670 ± 1050 1760 ± 1050 0.254
Missing 44 (10.2%) 48 (6.1%) 54 (5.0%)

47.5 和CompareGroups比较

CompareGroups不能自定义复杂表头。但是胜在语法简单,自带P值!详情请参考前面的文章。