메르스, 중동호흡기증후군은 2015년 5월 21일 사우디아라비아 등을 거쳐 바레인을 방문한 68세 남성이 첫 확진 진단은 이후 크나큰 사회문제와 함께 향후 숙제를 남겨주었다.
NetMiner - MERS-CoV 웹사이트에 일자별로 데이터가 잘 정리되어 있다. 국문과 영문으로 두가지 언어로 제공되고 있으며 엑셀 파일을 메르스 네트워크 분석 데이터로 활용한다.
네트워크 분석을 위해서 필요한 데이터분석 연장을 준비한다. 데이터프레임으로 네트워크 분석에 필요한 데이터를 가져와서 graph_from_data_frame()
함수를 통해 igraph
객체로 변환하여 정적, 동적 네트워크 및 다양한 통계분석을 수행한다. 단, 데이터는 결점(Vertex, Node), 연결점(Edge, Link) 정보를 담고 있는 edgelist
형태로 자료구조를 사전에 정비해야만 된다.
# 0. 환경설정 ------------------
library(igraph)
library(tidyverse)
library(threejs)
library(readxl)
library(ggpubr)
library(forcats)
library(extrafont)
loadfonts()
NetMiner - MERS-CoV에서 다운로드 받은 엑셀 파일에서 필요한 결점(Vertex, Node), 연결점(Edge, Link) 쉬트를 read_excel
함수를 통해 불러온다.
그리고 나서 graph_from_data_frame()
함수를 통해 igraph
네트워크 객체를 생성하면 데이터 준비는 모두 끝났다.
# 1. 데이터 가져오기 ------
## 1.1. 데이터 읽어들이기
mers_vert <- read_excel("data/(한국어)2015-10-02xlsx.xlsx", sheet="확진자")
colnames(mers_vert) <-c("확진자", "성별", "나이", "확진일", "현상태", "현상태_판정일자",
"감염병원", "감염지역", "감염 이유", "비고")
mers_edge <- read_excel("data/(한국어)2015-10-02xlsx.xlsx", sheet="확진자간 link")
## 1.2. 네트워크 데이터 변환
mers_ng <- graph_from_data_frame(d = mers_edge, vertices = mers_vert, directed = TRUE)
결점(Vertex)에서 성별을 뽑아 색상을 달리 한 후에 메르스 igraph 객체를 시각화해보자.
# 2. 네트워크 데이터 변환 ------
V(mers_ng)$color <- ifelse(V(mers_ng)$성별 == "f", "red", "blue")
# 3. 네트워크 데이터 변환 ------
plot(mers_ng,
vertex.label.color = "black",
vertex.label.cex = 0.8,
vertex.size = 0,
edge.color = 'black',
edge.width = 1,
edge.arrow.size = 0.1,
layout = layout_nicely(mers_ng))
메르스 감염 네트워크를 이해하기 필요한 기본적인 정보를 살펴본다. 먼저 네트워크 내 결점(Vertex, Node)와 연결선(Edge, Link) 갯수를 살펴본다. vcount
, ecount
도 있고, gorder
, gsize
함수도 있지만 동일하다.
그리고, farthest_vertices
, get_diameter
함수를 통해 네트워크 노드간 떨어진 거리도 파악한다.
# 2. 네트워크 기술통계 ------
## 2.1. 결점(Vertex, Node)와 연결선(Edge, Link) 갯수
vcount(mers_ng)
[1] 186
gorder(mers_ng)
[1] 186
gsize(mers_ng)
[1] 181
ecount(mers_ng)
[1] 181
## 2.2. 네트워크 크기
farthest_vertices(mers_ng)
$vertices
+ 2/186 vertices, named, from c6d2e11:
[1] M00001 M00099
$distance
[1] 3
get_diameter(mers_ng)
+ 4/186 vertices, named, from c6d2e11:
[1] M00001 M00014 M00050 M00099
메르스 데이터는 양방향이 아니라 특정 환자가 다른 환자를 감염시키는 구조라 mode
는 out
만 의미가 있다.
ego()
함수를 통해 특정 결점(vertex), ‘M00014’ 환자와 떨어진 정도(2
)를 지정하면 근처 결점을 확인할 수 있다.incident()
함수는 특정 결점과 연결된 연결선을 확인하는데 도움을 준다.ego(mers_ng, 2, 'M00014', mode = c('out'))
[[1]]
+ 95/186 vertices, named, from c6d2e11:
[1] M00014 M00035 M00037 M00039 M00040 M00041 M00046 M00047 M00048 M00049
[11] M00050 M00055 M00056 M00057 M00058 M00059 M00060 M00061 M00062 M00063
[21] M00064 M00065 M00066 M00067 M00068 M00069 M00070 M00071 M00072 M00073
[31] M00074 M00075 M00076 M00077 M00078 M00079 M00080 M00081 M00089 M00090
[41] M00091 M00096 M00097 M00098 M00100 M00102 M00103 M00104 M00105 M00110
[51] M00111 M00112 M00113 M00114 M00116 M00118 M00120 M00121 M00122 M00123
[61] M00124 M00125 M00126 M00131 M00132 M00134 M00135 M00136 M00137 M00138
[71] M00139 M00140 M00142 M00146 M00177 M00099 M00162 M00164 M00133 M00145
[81] M00150 M00160 M00165 M00167 M00168 M00170 M00173 M00176 M00179 M00153
[91] M00175 M00147 M00186 M00169 M00181
incident(mers_ng, 'M00014', mode = c("all"))
+ 75/181 edges from c6d2e11 (vertex names):
[1] M00014->M00035 M00014->M00037 M00014->M00039 M00014->M00040
[5] M00014->M00041 M00014->M00046 M00014->M00047 M00014->M00048
[9] M00014->M00049 M00014->M00050 M00014->M00055 M00014->M00056
[13] M00014->M00057 M00014->M00058 M00014->M00059 M00014->M00060
[17] M00014->M00061 M00014->M00062 M00014->M00063 M00014->M00064
[21] M00014->M00065 M00014->M00066 M00014->M00067 M00014->M00068
[25] M00014->M00069 M00014->M00070 M00014->M00071 M00014->M00072
[29] M00014->M00073 M00014->M00074 M00014->M00075 M00014->M00076
[33] M00014->M00077 M00014->M00078 M00014->M00079 M00014->M00080
[37] M00014->M00081 M00014->M00089 M00014->M00090 M00014->M00091
+ ... omitted several edges
메르스 전파에서 중요한 역할을 한 ‘M00014’ 환자와 ‘M00001’ 환자 사이에 어떤 환자가 있는지 파악하는데 neighbors()
함수로 특정 네트워크를 떼어내고 나서, intersection()
함수를 사용하게 되면 중간 매개환자도 쉽게 파악할 수 있다.
## 2.3. 교차 결점
mers_14 <- neighbors(mers_ng, 'M00014', mode = c('all'))
mers_01 <- neighbors(mers_ng, 'M00001', mode = c('all'))
intersection(mers_14, mers_01)
+ 1/186 vertex, named, from c6d2e11:
[1] M00037
네트워크가 크면 중요 결점(vertex)를 시각적으로 식별하는 것이 쉽지는 않다. 이런 경우 degree()
함수를 사용해서 나가는 도수(Out Degree)를 통계량으로 설정하여 일반적인 결점과 중요한 결점을 파악한다.
# 3. 핵심 결점(vertex) 식별 ------
## 3.1. 나가는 도수(Out Degree) 기준 중요 결점 식별
mers_outd <- degree(mers_ng, mode = c("out"))
table(mers_outd)
mers_outd
0 1 2 3 6 10 23 31 74
155 17 7 2 1 1 1 1 1
which.max(mers_outd)
M00014
14
## 3.2. 나가는 도수 히스토그램
mers_outd_df <- data.frame(mers_outd)
mers_outd_df$mers_id <- row.names(mers_outd_df)
mers_outd_df %>%
rename(연결중앙성 = mers_outd) %>%
ggplot(aes(x=연결중앙성)) +
geom_density() +
labs(x="외부로 나가는 연결중앙성", y="밀도") +
theme_pubr(base_family = "NanumGothic")
make_ego_graph()
함수를 통해 특정 노드 나가는 도수가 가장 큰 값을 갖는 ’M00014’를 중심으로 그래프를 생성하고 나서, 이에 대한 거리를 계산한다. 그리고 거리를 각 노드에 넣어 시각화를 완성한다.
## 3.3. 나가는 도수 거리별 시각화
M00014 <- make_ego_graph(mers_ng, diameter(mers_ng), nodes = 'M00014', mode = c("all"))[[1]]
mers_dists <- distances(M00014, "M00014")
colors <- c("black", "red", "orange", "blue")
V(M00014)$color <- colors[mers_dists+1]
plot(M00014,
vertex.label = mers_dists,
vertex.label.color = "white",
vertex.label.cex = 1,
edge.color = 'black',
vertex.size = 5,
edge.arrow.size = .05,
main = "메르스 최초 환자로부터 거리(Geodesic Distances)")
고유값 중앙성(eigen_centrality)을 기준으로 중요 결점을 파악하고 이를 시각화하는 것도 가능하다.
# 4. 고유값 기준 ---------------
mers_ng_ec <- eigen_centrality(mers_ng)
which.max(mers_ng_ec$vector)
M00014
14
plot(mers_ng,
vertex.label.color = "black",
vertex.label.cex = 0.8,
vertex.size = 20*(mers_ng_ec$vector),
edge.color = 'gray88',
edge.arrow.size = .05,
main = "메르스 전파 중요 환자 - 고유값 중심점 기준"
)
네트워크 시각화에 메르스 병원을 시각화하는 경우 먼저 V(mers_ng)$color
에 색상을 정의한다. fct_lump()
함수를 사용하면 손쉽게 범주를 나눌 수 있다.
# 5. 병원 시각화 ------
V(mers_ng)$color <- fct_lump(V(mers_ng)$감염병원, 7)
plot(mers_ng,
vertex.label = V(mers_ng)$감염병원,
vertex.label.color = "black",
vertex.label.cex = 0.9,
vertex.label.family="NanumGothic",
edge.color = 'black',
vertex.size = 5,
edge.arrow.size = .05,
main = "메르스 감염병원")
동적(static), 정적(dynamic), 인터랙티브(interactive) 네트워크 시각화 팩키지가 다수 존재한다. R Base 그래픽 시스템에 기초한 계열과 최근 그래프 문법(grammar of graphcis)에 기초한 계열 이 정적그래프에 존재하고, 동적, 인터랙티브, 애니메이션 계열이 별도로 존재한다.
graphjs(mers_ng,
vertex.shape = V(mers_ng)$name,
vertex.size = 0.1,
edge.color = 'darkgray',
main = "메르스 전파 네트워크"
)