1.Background


(1) Vit B12 개요


    ① Vit B12 정식명칭 : Cobalamin


    ② 결핍증 발생시


      신경정신학적, 혈액학적 측면에서 잠재적으로 심각한 악영향


      :사고 능력의 감소, 감정이나 행동의 변화, 정신병, 구강의 염증, 미각의 감소, 적혈구 감소, 심장기능 감소, 생식능력 감소 등


(2) Cobalamin(Vit B12)의 흡수과정


    ① 동물성 단백질 복용


    ② 위


      - 위에서 분비된 펩신, HCL이 동물성 단백질에서 Cobalamin을 분리해 냄.


      - 분리된 Cobalamin은 R-protein과 결합함.


      - Intrinsic Factor (IF) 역시 위에서 분비됨.


    ③ 십이지장, 담낭, 췌장


      - 십이지장에서 담낭과 췌장의 영향을 받음


      - 담즙으로 인해 Cobalamin-R complex


      - 췌장으로인해 이를 분해하여 Free Cobalamin을 생성


    ④ 소장


      - Cobalamin과 Instrinsic factor 결합


    ⑤ 소장의 마지막 80cm


      - Cobalamin 흡수


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




(3) 선행논문 조사


    ① 수술 후 혈중 Vit B 12 수치의 저하가 발생함 확인 (Total 군에서 저명함).


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


    ② 약 4년 후 Total Gastrectomy 군에서 100%의 환자가 결핍증이 발생 함. (Serum Vit B12 < 200)


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



(4) SMC gastrectomy 추이


    ① Gastrectomy 수술 후 검사 처방 follow up까지 걸리는 시간, 추적관찰 횟수


tidy_z <- tidy_long2[,-3] #result 값을 지우고 수술 이후 날짜 값만 추출
z3<- spread(tidy_z, order, date) #long form에서 wide form으로 변환 order기준으로 date값을 넣어줌 
boxplot(z3[,2:7]) #방문 횟수에 따른 기간 f.u 


    ② Total Gastrectomy 또는 Partial gastrectomy를 받은 환자에서 Vitamin B12 검사 처방 건


ph<-c(312,52,13,12,2)
ph<-table(try_simple$count)
barplot(ph, width = 1,main = "Vitamin B12 Lab test order rate",ylab = "Frequency", xlab='F/U count',col = "grey" )


    ② -1. Total gastrectomy 받은 환자의 Vitmin B12 검사 처방 건


ph1<-c(138,22,6,2,1)
ph1<-table(try_simple1$count)
barplot(ph1, width = 1,main = "Vitamin B12 Lab test order rate-Total",ylab = "Frequency", xlab='F/U count',col = "grey")


    ② -2. Partial gastrectomy 받은 환자의 Vitmin B12 검사 처방 건


ph2<-c(174,30,7,10,1)
ph2<-table(try_simple2$count)
barplot(ph2, width = 1,main = "Vitamin B12 Lab test order rate-patial",ylab = "Frequency", xlab='F/U count',col = "grey")


2.MEDTHOD


(1) 다윈C 유래 데이터


    <데이터의 제한점>


      - 9~999일까지만 일자 선택 가능.


      - 동일 항목은 최대 10번 까지만 추출 가능.


      - 정보 및 약 처방 부분을 해석하는 데에 제한이 있음.


      - 0~999일까지 Vit B12, 복합 Vit 제제를 1회라도 처방 받은 사람은 Y, 그 외는 N로 판단.


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



(2) 데이터 전처리


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



    ① 위암환자 (N:37890)


      - CSV file read


      - 필요하지 않은 Column 정리


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

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


      - Date 형식 맞추기


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


temp_vit <- read.csv("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)


    ⑥ 10일 이후 4년 이내 검사 1회이상 시행 한 환자군 선택(N:392)


      - Total gastrectomy를 한 환자의 퇴원일은 수술일로부터 평균적으로 10일이며,

       선행논문에 따르면 4년 이내에 아무 조치를 취하지 않을 경우 Vit B12 Deficiency 발생률이 100%라고 했으므로

       DataSet 기간을 10day< X < 4y로 잡고 그 중에서 검사를 1회 이상 한 환자군을 선택함.


      - 데이터 전처리 과정


        &nbsp a. 환자번호를 기준으로, 날짜순으로 새로운 id 부여함.


        &nbsp b. 중증도 분류를 위해 3가지 군으로 나눔


        &nbsp &nbsp 정상수치(x>500), 위험수치(200< x <500), 결핍수치(x <200)


          c. longform 데이터에 Characteristic 이식함.


#7. 10일 이하의 사람을 날리기
tidy_long1 <- tidy_long %>% filter(date > 10) %>% filter(date < 365*4) #타겟 시간의 안쪽의 환자들을 subset. 
tidy_long2 <- tidy_long1[-2] # column num을 제거
tidy_long2 <- data.table(tidy_long2) #데이터 테이블 명령어 사용위해
tidy_long2[, order := order(date), by = ID.1]

#카테고리컬 리절트 만들기
tidy_long3 <- 
  tidy_long2 %>%
    mutate(categorical_result = 
             ifelse(result <= 200, 1, 
                    ifelse(result <=500 & result > 200, 2, 3)
                    )
          )

#롱폼 데이터에 characteristic 이식
temp_df <- tidy_long2 %>% unite(date_result, date, result, sep = "_") %>% spread(order, date_result)

temp_df2 <- temp_df %>%
  separate(`1`, c("date1", "result1"), sep = "\\_")%>%
  separate(`2`, c("date2", "result2"), sep = "\\_")%>%
  separate(`3`, c("date3", "result3"), sep = "\\_")%>%
  separate(`4`, c("date4", "result4"), sep = "\\_")%>%
  separate(`5`, c("date5", "result5"), sep = "\\_")%>%
  separate(`6`, c("date6", "result6"), sep = "\\_")

temp_df2[,2:13] <- lapply(temp_df2[,2:13], as.numeric)


    ⑦ 최종 DataSet 도출 (N:392)


        a. tidy_wideform: Total or Patial gastrectomy 이후 검사결과가 있는 환자/데이터 형식은 wideform


        b. tidy_longform: Total or Patial gastrectomy 이후 검사결과가 있는 환자/데이터 형식은 wideform


        c. total_wide: Total gastrectomy 이후 검사결과가 있는 환자/데이터 형식은 wideform


        d. total_long: Total gastrectomy 이후 검사결과가 있는 환자/데이터 형식은 longform


        e. patial_long: Patial gastrectomy 이후 검사결과가 있는 환자/데이터 형식은 longform


        f. patial_wide: Patial gastrectomy 이후 검사결과가 있는 환자/데이터 형식은 wideform


tidy_wideform <- left_join(temp_df2, post_op[c(1:11,32)], by = "ID.1")
tidy_longform <- left_join(tidy_long3, post_op[c(1:11,32)], by = "ID.1")

total_wide <- tidy_wideform %>% 
  filter(Scode.12 %in% opcode_t)
total_long <- tidy_longform %>%
  filter(Scode.12 %in% opcode_t)
partial_wide <- tidy_wideform %>% 
  filter(Scode.12 %in% opcode_p)
partial_long <- tidy_longform %>%
  filter(Scode.12 %in% opcode_p)


3. result


(1) Follow up 현황


knitr::include_graphics("C:/Users/Mina Kim/Desktop/pic8.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) 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)
# 마지막으로 측정된 비타민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)


(3) [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).


(4) [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))


(5) 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)))


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

#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,) 


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


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


    - 시각화 후 해석


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


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


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


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