이번에 제가 책을 쓰면서 그동안 만들어 두었던 여러 함수들과 데이타들을 모아서 moonBook 이라는 패키지로 만들었읍니다. CRAN과 github에 등록했읍니다. CRAN에는 version 0.1.0이 등록되었고 github에는 version 0.1.1이 등록되었읍니다.최신 버젼에는 mytable의 결과를 html과 csv로 변환하는 함수가 포함되어 있으니 github을 통해 설치하시는 것을 권합니다. CRAN에는 다시 올렸는데 과거의 예로 보아 upversion이 등록되려면 하루이틀 걸리니 github을 통해 설치하시길 권합니다. 패키지를 설치하는 방법은 다음과 같습니다.

install.packages("devtools")  # devtools가 설치되어 있지 않은 경우 설치
devtools::install_github("cardiomoon/moonBook")

하루이틀만 지나면 CRAN을 통해 하셔도 됩니다.

install.packages("moonBook")

이 패키지에는 두개의 데이타가 들어있읍니다. 하나는 급성관동맥증후군 환자의 데이타인 acs이고 또 하나는 요골동맥의 혈관내 초음파 데이타인 radial입니다. 이 패키지의 주요 기능은 descriptive statistics 표를 만들어주는 것입니다. 의학논문을 작성할때 결과의 첫번째 표에 해당됩니다. 예를 들어 acs데이타에서 진단명(Dx)에 따른 descriptive statistics를 표로 만들려면 다음과 같이 합니다. mytable()함수를 씁니다.

require(moonBook)  # 패키지불러오기 
data(acs)          # 데이타 불러오기        
mytable(Dx~age+sex,data=acs)

             Descriptive Statistics by 'Dx'             
_________________________________________________________ 
              NSTEMI       STEMI    Unstable Angina   p  
              (N=153)     (N=304)       (N=400)    
--------------------------------------------------------- 
 age        64.3 ± 12.3 62.1 ± 12.1   63.8 ± 11.0   0.073
 sex                                                0.012
   - Female 50 (32.7%)  84 (27.6%)    153 (38.2%)        
   - Male   103 (67.3%) 220 (72.4%)   247 (61.8%)        
--------------------------------------------------------- 

이때 formula를 사용하는데 틸트표시(~)의 왼쪽은 그룹변수이고 오른쪽은 보고자하는 변수들을 넣어줍니다. 다 아시겠지만 “.”은 전부를 뜻하고 “+”,“-”를 쓸수 있읍니다. 데이타를 전부 보려면 다음과 같이 하면 됩니다.

res=mytable(Dx~.,data=acs)

version 0.1.1에는 이 표를 html형식의 표로 만들어주는 myhtml()함수와 csv화일로 만들어주는 mycsv() 함수가 포함되어 있읍니다.

myhtml(res)
Descriptive Statistics by ‘Dx’
Dx NSTEMI
(N=153)
STEMI
(N=304)
Unstable Angina
(N=400)
p
age 64.3 ± 12.3 62.1 ± 12.1 63.8 ± 11.0 0.073
sex 0.012
  • Female
50 (32.7%) 84 (27.6%) 153 (38.2%)
  • Male
103 (67.3%) 220 (72.4%) 247 (61.8%)
cardiogenicShock 0.000
  • No
149 (97.4%) 256 (84.2%) 400 (100.0%)
  • Yes
4 ( 2.6%) 48 (15.8%) 0 ( 0.0%)
entry 0.001
  • Femoral
58 (37.9%) 133 (43.8%) 121 (30.2%)
  • Radial
95 (62.1%) 171 (56.2%) 279 (69.8%)
EF 55.0 ± 9.3 52.4 ± 9.5 59.2 ± 8.7 0.000
height 163.3 ± 8.2 165.1 ± 8.2 161.7 ± 9.7 0.000
weight 64.3 ± 10.2 65.7 ± 11.6 64.5 ± 11.6 0.361
BMI 24.1 ± 3.2 24.0 ± 3.3 24.6 ± 3.4 0.064
obesity 0.186
  • No
106 (69.3%) 209 (68.8%) 252 (63.0%)
  • Yes
47 (30.7%) 95 (31.2%) 148 (37.0%)
TC 193.7 ± 53.6 183.2 ± 43.4 183.5 ± 48.3 0.057
LDLC 126.1 ± 44.7 116.7 ± 39.5 112.9 ± 40.4 0.004
HDLC 38.9 ± 11.9 38.5 ± 11.0 37.8 ± 10.9 0.501
TG 130.1 ± 88.5 106.5 ± 72.0 137.4 ± 101.6 0.000
DM 0.209
  • No
96 (62.7%) 208 (68.4%) 249 (62.2%)
  • Yes
57 (37.3%) 96 (31.6%) 151 (37.8%)
HBP 0.002
  • No
62 (40.5%) 150 (49.3%) 144 (36.0%)
  • Yes
91 (59.5%) 154 (50.7%) 256 (64.0%)
smoking 0.000
  • Ex-smoker
42 (27.5%) 66 (21.7%) 96 (24.0%)
  • Never
50 (32.7%) 97 (31.9%) 185 (46.2%)
  • Smoker
61 (39.9%) 141 (46.4%) 119 (29.8%)

기존에 있었던 compareGroups라는 패키지에서 영감을 많이 얻었는데 compareGroups패키지의 경우 combined table을 만들려면 조금 복잡했읍니다. 제가 만든 mytable()함수는 combined table을 아주 쉽게 만들 수 있읍니다. 예를 들어 전체 환자를 성별로 나누고 남자 데이타, 여자데이타를 따로 당뇨 유무에 따라 표를 만들려면 다음과 같이 하면 됩니다.

res1=mytable(sex+DM~.,data=acs)
res1

                 Descriptive Statistics stratified by 'sex' and 'DM'                
_____________________________________________________________________________________ 
                                    Male                             Female             
                     -------------------------------- ------------------------------- 
                          No           Yes        p        No          Yes        p  
                       (N=380)       (N=190)           (N=173)      (N=114)        
------------------------------------------------------------------------------------- 
 age                 60.9 ± 11.5   60.1 ± 10.6  0.472 69.3 ± 11.4  67.8 ±  9.7  0.257
 cardiogenicShock                               0.685                           0.296
   - No              355 (93.4%)   175 (92.1%)        168 (97.1%)  107 (93.9%)       
   - Yes              25 ( 6.6%)   15 ( 7.9%)          5 ( 2.9%)    7 ( 6.1%)        
 entry                                          0.552                           0.665
   - Femoral         125 (32.9%)   68 (35.8%)          74 (42.8%)   45 (39.5%)       
   - Radial          255 (67.1%)   122 (64.2%)         99 (57.2%)   69 (60.5%)       
 Dx                                             0.219                           0.240
   - NSTEMI           71 (18.7%)   32 (16.8%)          25 (14.5%)   25 (21.9%)       
   - STEMI           154 (40.5%)   66 (34.7%)          54 (31.2%)   30 (26.3%)       
   - Unstable Angina 155 (40.8%)   92 (48.4%)          94 (54.3%)   59 (51.8%)       
 EF                  56.5 ±  8.3   53.9 ± 11.0  0.007 56.0 ± 10.1  56.6 ± 10.0  0.655
 height              168.1 ±  5.8 167.5 ±  6.7  0.386 153.9 ±  6.5 153.6 ±  5.8 0.707
 weight              68.1 ± 10.4   69.8 ± 10.2  0.070 56.5 ±  8.7  58.4 ± 10.0  0.106
 BMI                 24.0 ±  3.1   24.9 ±  3.5  0.005 23.8 ±  3.2  24.8 ±  4.0  0.046
 obesity                                        0.027                           0.359
   - No              261 (68.7%)   112 (58.9%)        121 (69.9%)   73 (64.0%)       
   - Yes             119 (31.3%)   78 (41.1%)          52 (30.1%)   41 (36.0%)       
 TC                  184.1 ± 46.7 181.8 ± 44.5  0.572 186.0 ± 43.1 193.3 ± 60.8 0.274
 LDLC                117.9 ± 41.8 112.1 ± 39.4  0.115 116.3 ± 35.2 119.8 ± 48.6 0.519
 HDLC                38.4 ± 11.4   36.8 ±  9.6  0.083 39.2 ± 10.9  38.8 ± 12.2  0.821
 TG                  115.2 ± 72.2 153.4 ± 130.7 0.000 114.2 ± 82.4 128.4 ± 65.5 0.112
 HBP                                            0.000                           0.356
   - No              205 (53.9%)   68 (35.8%)          54 (31.2%)   29 (25.4%)       
   - Yes             175 (46.1%)   122 (64.2%)        119 (68.8%)   85 (74.6%)       
 smoking                                        0.386                           0.093
   - Ex-smoker       101 (26.6%)   54 (28.4%)          34 (19.7%)   15 (13.2%)       
   - Never            77 (20.3%)   46 (24.2%)         118 (68.2%)   91 (79.8%)       
   - Smoker          202 (53.2%)   90 (47.4%)          21 (12.1%)   8 ( 7.0%)        
------------------------------------------------------------------------------------- 
myhtml(res1)
Descriptive Statistics stratified by sex and DM
sex Male Female
DM No
(N=380)
Yes
(N=190)
p No
(N=173)
Yes
(N=114)
p
age 60.9 ± 11.5 60.1 ± 10.6 0.472 69.3 ± 11.4 67.8 ± 9.7 0.257
cardiogenicShock 0.685 0.296
  • No
355 (93.4%) 175 (92.1%) 168 (97.1%) 107 (93.9%)
  • Yes
25 ( 6.6%) 15 ( 7.9%) 5 ( 2.9%) 7 ( 6.1%)
entry 0.552 0.665
  • Femoral
125 (32.9%) 68 (35.8%) 74 (42.8%) 45 (39.5%)
  • Radial
255 (67.1%) 122 (64.2%) 99 (57.2%) 69 (60.5%)
Dx 0.219 0.240
  • NSTEMI
71 (18.7%) 32 (16.8%) 25 (14.5%) 25 (21.9%)
  • STEMI
154 (40.5%) 66 (34.7%) 54 (31.2%) 30 (26.3%)
  • Unstable Angina
155 (40.8%) 92 (48.4%) 94 (54.3%) 59 (51.8%)
EF 56.5 ± 8.3 53.9 ± 11.0 0.007 56.0 ± 10.1 56.6 ± 10.0 0.655
height 168.1 ± 5.8 167.5 ± 6.7 0.386 153.9 ± 6.5 153.6 ± 5.8 0.707
weight 68.1 ± 10.4 69.8 ± 10.2 0.070 56.5 ± 8.7 58.4 ± 10.0 0.106
BMI 24.0 ± 3.1 24.9 ± 3.5 0.005 23.8 ± 3.2 24.8 ± 4.0 0.046
obesity 0.027 0.359
  • No
261 (68.7%) 112 (58.9%) 121 (69.9%) 73 (64.0%)
  • Yes
119 (31.3%) 78 (41.1%) 52 (30.1%) 41 (36.0%)
TC 184.1 ± 46.7 181.8 ± 44.5 0.572 186.0 ± 43.1 193.3 ± 60.8 0.274
LDLC 117.9 ± 41.8 112.1 ± 39.4 0.115 116.3 ± 35.2 119.8 ± 48.6 0.519
HDLC 38.4 ± 11.4 36.8 ± 9.6 0.083 39.2 ± 10.9 38.8 ± 12.2 0.821
TG 115.2 ± 72.2 153.4 ± 130.7 0.000 114.2 ± 82.4 128.4 ± 65.5 0.112
HBP 0.000 0.356
  • No
205 (53.9%) 68 (35.8%) 54 (31.2%) 29 (25.4%)
  • Yes
175 (46.1%) 122 (64.2%) 119 (68.8%) 85 (74.6%)
smoking 0.386 0.093
  • Ex-smoker
101 (26.6%) 54 (28.4%) 34 (19.7%) 15 (13.2%)
  • Never
77 (20.3%) 46 (24.2%) 118 (68.2%) 91 (79.8%)
  • Smoker
202 (53.2%) 90 (47.4%) 21 (12.1%) 8 ( 7.0%)

위의 명령어는 아래와 같이 한줄로 써도 되지만 저는 위와 같이 두줄로 쓰는 것을 선호합니다.

myhtml(mytable(sex+Dx~age+DM+HBP,data=acs))
Descriptive Statistics stratified by sex and Dx
sex Male Female
Dx NSTEMI
(N=103)
STEMI
(N=220)
Unstable Angina
(N=247)
p NSTEMI
(N=50)
STEMI
(N=84)
Unstable Angina
(N=153)
p
age 61.1 ± 11.6 59.4 ± 11.7 61.4 ± 10.6 0.133 70.9 ± 11.4 69.1 ± 10.4 67.7 ± 10.7 0.177
DM 0.219 0.240
  • No
71 (68.9%) 154 (70.0%) 155 (62.8%) 25 (50.0%) 54 (64.3%) 94 (61.4%)
  • Yes
32 (31.1%) 66 (30.0%) 92 (37.2%) 25 (50.0%) 30 (35.7%) 59 (38.6%)
HBP 0.016 0.084
  • No
43 (41.7%) 122 (55.5%) 108 (43.7%) 19 (38.0%) 28 (33.3%) 36 (23.5%)
  • Yes
60 (58.3%) 98 (44.5%) 139 (56.3%) 31 (62.0%) 56 (66.7%) 117 (76.5%)

mylatex 함수는 출력물의 폰트 크기를 조절할 수 있읍니다.

out=mytable(sex~age+Dx,data=acs)
for(i in c(3,5)) 
    mylatex(out,size=i,caption=paste("Table ",i,". Fontsize=",i,sep=""))

latextest.png

mylatex(mytable(sex+DM~age+Dx,data=acs),size=4)

latextest2.png

그 외에도 유용한 plot들을 만들어주는 함수들도 몇 개 있는데 하나만 소개하면 다음과 같습니다.

densityplot(age~sex,data=acs)

out=mytable(sex~age+Dx,data=acs)
myhtml(out)
Descriptive Statistics by ‘sex’
sex Female
(N=287)
Male
(N=570)
p
age 68.7 ± 10.7 60.6 ± 11.2 0.000
Dx 0.012
  • NSTEMI
50 (17.4%) 103 (18.1%)
  • STEMI
84 (29.3%) 220 (38.6%)
  • Unstable Angina
153 (53.3%) 247 (43.3%)
myhtml(mytable(sex+DM~age+Dx,data=acs))
Descriptive Statistics stratified by sex and DM
sex Male Female
DM No
(N=380)
Yes
(N=190)
p No
(N=173)
Yes
(N=114)
p
age 60.9 ± 11.5 60.1 ± 10.6 0.472 69.3 ± 11.4 67.8 ± 9.7 0.257
Dx 0.219 0.240
  • NSTEMI
71 (18.7%) 32 (16.8%) 25 (14.5%) 25 (21.9%)
  • STEMI
154 (40.5%) 66 (34.7%) 54 (31.2%) 30 (26.3%)
  • Unstable Angina
155 (40.8%) 92 (48.4%) 94 (54.3%) 59 (51.8%)

csv화일로 만들 때는 다음과 같이 하면 됩니다.

mycsv(out,file="test.csv")

생존분석에 쓰이는 cox proportional hazard model을 자동화하는 함수 mycph()와 hazard ratio를 쉽게 plot하는 HRplot함수도 만들었읍니다.

require(survival)
attach(colon)
colon$TS=Surv(time,status==1)
out=mycph(TS~.,data=colon)

 mycph : perform coxph of individual expecting variables

 Call: TS ~ ., data= colon 

study  was excluded : NaN
status  was excluded : infinite
out
            HR  lcl  ucl     p
id        1.00 1.00 1.00 0.317
rxLev     0.98 0.84 1.14 0.786
rxLev+5FU 0.64 0.55 0.76 0.000
sex       0.97 0.85 1.10 0.610
age       1.00 0.99 1.00 0.382
obstruct  1.27 1.09 1.49 0.003
perfor    1.30 0.92 1.85 0.142
adhere    1.37 1.16 1.62 0.000
nodes     1.09 1.08 1.10 0.000
differ    1.36 1.19 1.55 0.000
extent    1.78 1.53 2.07 0.000
surg      1.28 1.11 1.47 0.001
node4     2.47 2.17 2.83 0.000
time      0.98 0.98 0.98 0.000
etype     0.81 0.71 0.92 0.001
HRplot(out)

HRplot(out,type=2,show.CI=TRUE,pch=2,sig=0.05)

HRplot(out,type=3,show.CI=TRUE,pch=2,cex=2,sig=0.05,
       main="Hazard ratios of significant variables")