1.주제:위암 환자의 수술 후 Vitamin B12 예후 조사


2.분석 목표


 - 수술을 받은 위암환자에서 Vit B12 의 검사처방과 약처방의 데이터 탐색


3.분석 자료


    (1) Source


      Darwin-C 추출 데이터


    (2) 연구 모집단 (Study population)


      A. 특성


        2000.1.1 ~ 2017.5.31 에 암 진단을 받은 사람 중 상병이 위암인 환자


      B. 표본의 크기


        위암환자 (N: 37,890)


    (3) 변수(Variables of interest) 및 특징


knitr::include_graphics("C:/Users/Mina Kim/Desktop/pic11.PNG")


4.분석 방법


    (1) 전처리


knitr::include_graphics("C:/Users/Mina Kim/Desktop/pic8.PNG")



    ① 위암환자 (N:37890)


      - CSV file read


      - 필요하지 않은 Column 정리


      - 한글로 되어 있는 Column명을 영어로 바꿔주기

      (Column Name이 영어로 되어 있으면 Markdown에서 Data가 잘 읽히지 않음)


      - Date 형식 맞추기


      - 검사 처방일로부터 수술일을 뺀 값으로 값 변경(추후 DataSet을 편하게 이용하기 위해 미리 전처리 작업함)


temp_vit <- read.csv("C:/Users/Mina Kim/Desktop/gastrectomy_order2.csv",header = T,  na.strings = c("", "NA"))
pt_gast_ca <- temp_vit[-c(1, 3, 7, 18, 19, 20, 21:26, seq(28, 82, 6), seq(29, 83, 6), seq(30,84, 6), seq(32,86,6), 86:89)]
names(pt_gast_ca)<-c("ID.1","Dg.3","IDg.4","Dcode.5","birth.7","sex.8","death.9","deathdate.10","Sdate.11","Scode.12","Sname.13","S2date.14","S2code.15","S2name.16","Vdate.26","Vvalue.30","Vdate.32","Vvalue.36","Vdate.38","Vvalue.42","Vdate.44","Vvalue.48","Vdate.50","Vvalue.54","Vdate.56","Vvalue.60","Vdate.62","Vvalue.66","Vdate.68","Vvalue.72","Vdate.74","Vvalue.78","Vdate.80","Vvalue.84","Vdate.89")
pt_gast_ca[c(2,3,5,8,9, 12, seq(15,35,2))] <- lapply(pt_gast_ca[c(2,3,5,8,9, 12, seq(15,35,2))], as.Date)
pt_gast_ca[seq(15,33,2)] <- lapply(pt_gast_ca[seq(15,33,2)], function(x) as.numeric(x - pt_gast_ca$Sdate.11))
#Data set: pt_gast_ca (N:37893)


    ② 위절제술을 2회 이상 시행한 환자군 제외 처리 (N:37727)


a<-pt_gast_ca[which(!is.na(pt_gast_ca$S2date.14)), ]
pt_op_only<- pt_gast_ca[which(is.na(pt_gast_ca$S2date.14)),-c(12,13,14)]


    ③ 수술 하지 않은 환자군 제외 처리(N:20995)


      - 위암 환자면서 수술 받지 않은 환자군 Dataset: Nonsurg


      - 위암 환자면서 수술 받은 환자군 Dataset:pt_postop


pt_postop <- pt_op_only[which(!is.na(pt_op_only$Sdate.11)), ] 
Nonsurge <- pt_op_only[which(is.na(pt_op_only$Sdate.11)), ] 


    ④ 2013.05.31 이후에 수술 시행한 군 제외 처리(N:15952)


      - 4년의 Vit B12 처방을 추적해야 하기 때문에, 마지막 날짜(2013.05.31) 이후 수술 한 환자군은 제외함.


post_op <- pt_postop[which(pt_postop$Sdate.11- as.Date("2013-05-31") < 0), ]


    ⑤ 수술 전 Vit B12 Deficiency 가 있었던 환자군 제외 처리(N:15951)


      - Vitamin B12 결과와 처방 날짜로 수술 전부터 Vitamin B12 Deficiency가 있었던 환자군을 제외처리함.


      - Dataset: post_op_n

        Post_op(위암환자&수술받음)에서 환자ID, VitB12 처방날짜, VitB12 수치 값으로 이루어진 컬럼을 추출함.


      - Dataset: z

        a. post_op_n Dataset의 컬럼에서 Vdate.26부터 Vvalue.84에 해당하는 값들을 longform으로 바꿔줌.


        b. 바꿀때 컬럼이름이 영문명 . 숫자로 되어 있다는 것에 착안하여

       ’.’을 기준으로 영문명에 해당하는 내용은 temp, 숫자에 해당하는 내용은 num로 저장함.


        c. 첫번째 F/U에 해당하는 Vdate값과 Vvalue값은 묶어 1번으로 표시하고 이와 같은 방법으로 10회까지 처리


        d. 그 이후 Vdate는 date로 Vvalue는 result값으로 이름을 변경해줌.


        e. 다시 wideform으로 변경해 준 후


        f. 수술 전(date<0) Vit B12 Deficiency(result<200)이 있는 환자를 찾음.


        g. 이렇게 찾아낸 환자를 제외처리 시킴.


#tidy set
post_op_n <- post_op[c(1,12:31)]

#z 는 manipulation을 위한 temporary data frame
z<-post_op_n %>% 
  gather(temp, value, Vdate.26:Vvalue.84) %>% 
  separate(col = temp, into = c("temp", "num"))

#다음을 통일함
z$num[z$num %in% c(26,30)] <- 1 
z$num[z$num %in% c(32,36)] <- 2
z$num[z$num %in% c(38,42)] <- 3
z$num[z$num %in% c(44,48)] <- 4
z$num[z$num %in% c(50,54)] <- 5
z$num[z$num %in% c(56,60)] <- 6
z$num[z$num %in% c(62,66)] <- 7
z$num[z$num %in% c(68,72)] <- 8
z$num[z$num %in% c(74,78)] <- 9
z$num[z$num %in% c(80,84)] <- 10
z$temp[z$temp == "Vdate"] <- "date"
z$temp[z$temp == "Vvalue"] <- "result"

# 와이드폼으로
z <- z %>% 
  spread(temp, value) 

#6 수술 전 vit B 12 200미만 제거
#z %>% 
#  dplyr::filter(date < 0) %>%
#  dplyr::filter(result <200) %>%
#  head()
# data set: Z (N:15952)


#이렇게 찾은사람을 날린 tidy set
tidy_long <- z[-which(z$ID.1 == "1F0822C849BD"), ]
# data set: tidy_long (N:159510)


    (2) 분석


      EDA, Descriptive analysis


    (3) 분석에 사용한 주요 R Package and function


      -데이터 전처리: dplyr, readr, reshape2, tidyr, plyr, data.table


      -데이터 시각화: ggplot2, moonBook


5. 결과보고


    (1) Follow up 현황


knitr::include_graphics("C:/Users/Mina Kim/Desktop/pic9.PNG")


도표를 그리기 위한 전처리 과정


try_simple<-total_wide[c(1,seq(3,by=2,length.out=6))]
for (i in 1:6){
  try_simple[i+7]<-!is.na(try_simple[,i+1])
}
try_simple$count<-rowSums(try_simple[,c(8:13)],na.rm=T)
try_simple<-try_simple[,-c(8:13)]
try_total<-join(total_wide,try_simple,type="left")
## Joining by: ID.1, result1, result2, result3, result4, result5, result6
try<-try_total

#4년안에 1번이라도 결핍이 있었던 사람 수
try1_1<-try[(try$result1<200)|(try$result2<200)|(try$result3<200)|(try$result4<200)|(try$result5<200),]
  try1_1<-try1_1[is.na(try1_1$ID.1)==FALSE,] #40

# 4년안에 첫번째 결핍이 생길 때까지의 기간
try1_2<-try1_1%>%
  mutate(first_period=
           ifelse(try1_1$result1<200,date1,
                  ifelse(try1_1$result2<200,date2,
                         ifelse(try1_1$result3<200,date3,
                                ifelse(try1_1$result4<200,date4,
                                       ifelse(try1_1$result5<200,date5,date6))))))

duration_first<-as.array(summary(try1_2$first_period))


    (2) [Total] 시간에 따른 vitamin B12 수치의 변화


ggplot(data = tidy_longform, aes(x = date, y = result, group = ID.1)) +
  geom_line() +
  geom_point(alpha = 0.3) +
  ggtitle("[Total] Change of vitamin B12 Inspection Numbers according to Time")+
  xlab("Date")+ ylab("vitamin B12 value")+
  theme(plot.title = element_text(size=14, hjust=0.5,face="bold"),
        axis.title.x = element_text(size=10),
        axis.title.y = element_text(size=10))+
  ylim(1,2000)
## Warning: Removed 10 rows containing missing values (geom_path).
## Warning: Removed 54 rows containing missing values (geom_point).


x축은 수술일로부터 진단일까지의 기간, y축은 vitamin B12 수치을 의미하며, 시간에 따른 각 환자들의 vitamin B12수치를 보여준다. Vitamin B12 수치는 수치형 변수이기 때문에 그래프가 산재되어있어 알아보기 어렵다.

(2)-1 [Categorical] 시간에 따른 수치의 categorical result 변화


ggplot(data = tidy_longform, aes(x = date, y = jitter(categorical_result, 0.2), group = ID.1)) +
  geom_line() +
  geom_point(alpha = 0.3) +
  ylim(0.5,3.5)+
  ggtitle("vit B12 <200 group's VitB12 variation ")+
  xlab("Date")+ ylab("vitamin B12 level")+
  theme(plot.title = element_text(size=14, hjust=0.5,face="bold"),
        axis.title.x = element_text(size=10),
        axis.title.y = element_text(size=10))


x축은 수술일로부터 진단일까지의 기간, y축은 범주화 된 vitamin B12 수치(200미만: 결핍(1), 200~500: 주의(2), 500이상: 정상(3))를 의미한다. 해당 그래프는 시간에 따라 각 환자들의 범주화된 vitamin B12수치 변화를 보여준다. 결핍군에 해당하는 부분(1)만을 구체적으로 보았을 때 떨어지는 방향으로 선들이 많은 것으로 보인다. 따라서 이를 좀 더 구체적으로 보기 위해 한번이라도 vitamin B12 결핍이 있었던 사람들에 대해 한번 더 그래프를 살펴보았다.

(2)-2 1번이라도 200이하로 떨어진 사람들의 vitamin B12 수치의 추이


try_simple_long1<-try_simple_long
try_simple_long1$count<-as.character(try_simple_long1$count)
ggplot(data=try_simple_long1, aes(x=factor(variable), y=value, colour = count)) +
  geom_line(aes(group = ID.1),size=1) + geom_point()+
  scale_colour_manual(values=brewer.pal(4,"Set2"))+
  ggtitle("Result of examination results of < 200 patients's vitamin B12 variation")+
  xlab("Lab F/U count")+ ylab("vitamin B12 value")+
  theme(plot.title = element_text(hjust=0.5,size=14, face="bold"),
        axis.title.x = element_text(size=10),
        axis.title.y = element_text(size=10))

total_post_op <- post_op %>%
  filter(Scode.12 %in% opcode_t) #n = 4080
partial_post_op <- post_op %>%
  filter(Scode.12 %in% opcode_p) #n = 11872

pt_id_exceptT <- total_wide$ID.1
pt_id_exceptP <- partial_wide$ID.1


exclusive_dataT <- total_post_op[-which(total_post_op$ID.1 %in% pt_id_exceptT), ]
exclusive_dataP <- partial_post_op[-which(partial_post_op$ID.1 %in% pt_id_exceptP), ]

a <- c(sum(!is.na(total_wide$Vdate.89)), nrow(total_wide)- sum(!is.na(total_wide$Vdate.89)))
b <- c(sum(!is.na(partial_wide$Vdate.89)), nrow(partial_wide)-sum(!is.na(partial_wide$Vdate.89)))
c <- c(sum(!is.na(exclusive_dataT$Vdate.89)), nrow(exclusive_dataT)- sum(!is.na(exclusive_dataT$Vdate.89)))
d <- c(sum(!is.na(exclusive_dataP$Vdate.89)), nrow(exclusive_dataP)- sum(!is.na(exclusive_dataP$Vdate.89)))



vitamin B12 수치의 결핍을 좀 더 직관적으로 보여주기 위해 다음 그래프를 그렸다. x축은 환자들의 vitamin B12 검사 횟수를, y축은 범주화 된 vitamin B12 수치를 의미한다. 이를 통해 한 번이라도 수치에 결핍이 있던 환자들 중 2회 이상 검사를 받은 환자들의 범주화 된 vitamin B12 수치를 표시했다. 환자들의 마지막 검사 수치 결과가 결핍군에 많이 포함이 되어있는데, 그 이후 또 다른 follow up이 없는 것으로 보아 follow up이 잘 안되고 있음을 알 수 있다.

(3) 4년안에 처음 결핍이 생길 때까지의 기간


ggplot(data=try1_2, aes(x="",y=first_period)) + 
  geom_boxplot(fill="slateblue",position=position_dodge(width=0.5)) +
  guides(fill=FALSE) + coord_flip()+
  #scale_x_discrete()
  ggtitle("A period of time until the first deficiency occurs within four years")+
  xlab(" ")+ ylab("duration")+
  theme(plot.title = element_text(hjust=0.5,size=14, face="bold"),
        axis.title.x = element_text(size=10),
        axis.title.y = element_text(size=10))

#summary(try1_2$first_period)


Box plot에서 duration은 수술 이후에 검사를 받을 때까지의 일수를 나타낸다. 중간값이 700정도의 수치를 보이는 것을 통해, 수술 후 2년에서 2년 반 사이에 한번 쯤은 follow up을 해주는 것이 좋을 것으로 보인다.

# 마지막으로 측정된 비타민B12 수치값
try_simple_200<-try_simple[(try_simple$result1<200)|(try_simple$result2<200)|(try_simple$result3<200)|(try_simple$result4<200)|(try_simple$result5<200),]
try_simple_200<-try_simple_200[is.na(try_simple_200$ID.1)==FALSE,]#
try_simple_200<-try_simple_200[-which(try_simple_200$result3==32850),]#outlier처리

try_simple_long<-melt(try_simple_200,id=c("ID.1","count"))
try_simple_long$variable<-substr(try_simple_long$variable,7,7)
try_simple_long<-try_simple_long[is.na(try_simple_long$value)==FALSE,]
try_final<-do.call("rbind",
                   by(try_simple_long, INDICES=try_simple_long$ID.1, FUN=function(try_simple_long) try_simple_long[which.max(try_simple_long$variable), ]))

#최소 1번이라도 200이하로 떨어진 사람들 중 검사횟수가 2회 이상인 사람들의 마지막 수치값 summary
summary(try_final[try_final$count>1,]$value)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##    46.0   120.8   152.0   226.8   259.2   739.0
# Min. 1st Qu.  Median    Mean 3rd Qu.    Max.
# 46.0   120.8   152.0   226.8   259.2   739.0

library(colorspace)
library(ggplot2)
library(RColorBrewer)


(4) Vit B12 Deficiency 현황


knitr::include_graphics("C:/Users/Mina Kim/Desktop/pic10.PNG")


왼쪽은 선행논문에서 수행한 결과를 그래프로 나타낸 것이다. TG는 total gastrectomy를 한 군, DG는 partial gastrectomy를 한 군을 의미하며, x축은 수술 이후의 기간(단위: 월)로, y축은 결핍이 생긴 사람들의 누적퍼센트를 보여준다. 이를 통해 수술 후 4년 안에 결핍이 생겼음을 보인다. 오른쪽 그래프는 SMC데이터를 활용하여 똑 같은 방식으로 분석을 한 것인데, x축은 수술 이후의 기간(단위: 일)로, y축은 결핍이 생긴 사람들의 누적퍼센트를 보여준다. 선행논문에서는 4년 후에 100%의 환자들이 vitamin B12결핍이 생겼으나, SMC데이터를 활용한 분석에서는 수술 이후 4년 후에도 20%의 사람들만 결핍이 생긴 것으로 보아, 기존 RCT에서는 투약을 control하였으나, 우리 환자 군에서는 (결과가 없음에도) 약 처방을 하였기 때문이라는 해석이 가능할 수도 있다는 생각을 했다. 이를 직관적으로 살펴보기 위해 환자들의 약 처방 비율을 살펴 보았다.


(5) 수술 방법 별 비타민 적정 검사 시행 여부에 따른 약 처방 비율


setwd("C:/Users/Mina Kim/Desktop/Rcode")
#dev.off(dev.list()["RStudioGD"])   #clear
par(mfrow = c(1,2),
    mar=c(4,3,3,1),
    oma=c(0.5,0.5,2,0.5))
par(mfrow=c(1,2),oma = c(0, 0, 5, 0))
df1 <- data.frame(a,c)
df1 <- as.matrix(df1)
barplot(prop.table(df1, 2), 
        col = c("slateblue", "palevioletred"),
        main="total gastrectomy",
        cex.main=1,cex.lab=0.1,
        names.arg=c("Lab test(Y)","Lab test(N)"),
        #axis.arg=c("0%","20%","40%","60%","80%","10%")
        cex.axis=1, cex.names=0.8)
legend("bottom", c("Vitamin order(Y)", "Vitamin order(N)"), col=c("slateblue","palevioletred"), cex=0.8,lwd=3);

df2 <- data.frame(b,d)
df2 <- as.matrix(df2)
barplot(prop.table(df2, 2), 
        col = c("slateblue", "palevioletred"),
        main="partial gastrectomy",
        cex.main=1,cex.lab=0.1,
        names.arg=c("Lab test(Y)","Lab test(N)"),
        #axis.arg=c("0%","20%","40%","60%","80%","10%")
        cex.axis=1, cex.names=0.8)
legend("bottom", c("Vitamin order(Y)", "Vitamin order(N)"), col=c("slateblue","palevioletred"), cex=0.8, lwd=3);title("Percentage of medications ", outer = TRUE, cex = 1) 


위 그래프는 Vit B12 검사여부와, Vit 제제 처방여부를 연결하여 조사한 결과인데, total gastrectomy와 partial gastrectomy 두 군 모두 검사 여부와 상관없이 약 90%에 육박하는 환자들이 약품 처방을 함을 발견하였다. Gastrectomy 후 Vit B12 외 여러 영양소가 결핍되는 것은 이미 널리 알려져 있어 예방적으로 검사결과가 낮더라도 Vit B12를 처방하는 것으로 볼 수 있다. 그럼에도 불구하고, 검사를 시행한 군이, 그렇지 않은 군에 비해 미미하지만, 약품 처방을 더 잘 받음을 알 수 있었는데, 이는 의료진이 처방을 함으로써 Vit B 수치를 보게 되고, 이를 교정해야겠다는 것이 remind 되는것이 아닌가 추측해 보았다.



6. 분석 시 가장 어려웠던 점


    - 전처리 과정에서 근거에 기반하여 inclusion, exclusion criteria를 정하는 점


    - 시각화 후 해석


    - 얻어낸 해석을 통해 부족한 점을 보완하기 위해 자료를 새롭게 요청하고, 위 과정을 지속적으로 반복하는 점.


7. 가장 유용하게 사용한 R package/Function 등


    - tidyr, dplyr: 데이터를 전처리 하는데 유용하게 쓰였음.


    - ggplot: visualization에 유용하게 쓰였음.