1 지방선거 여론조사

나무위키 제7회 전국동시지방선거/여론조사를 통해서 2018년 6월 13일 예정된 제7회 전국동시지방선거 판세를 현재 시점(2018-05-20) 가늠해보자.

2 주요 격전지

제7회 지방선거 주요 격전지로 수도권(서울, 경기, 인천)과 경상남도를 주요 격전지로 선정하여 다양한 여론조사 기관에서 수행한 여론조사 결과를 정리해 보자.

2.1 서울시장

서울은 각 여론조사 기관에서 3자구도에서 양자구도를 염두에 둔 여론조사결과가 있어 흥미롭다. 서울시장 후보는 민주당 박원순, 자한당 김문수, 바른미래 안철수 후보가 경쟁중에 있다.

# 0. 환경설정 -----
library(tidyverse)
library(rvest)
library(lubridate)
library(extrafont)
loadfonts()
library(plotly)

# 1. 여론조사 데이터 가져오기 -----
## 1.1. 서울시장
### 1.1.1. URL 
namu_url <- "https://namu.wiki/w/%EC%A0%9C7%ED%9A%8C%20%EC%A0%84%EA%B5%AD%EB%8F%99%EC%8B%9C%EC%A7%80%EB%B0%A9%EC%84%A0%EA%B1%B0/%EC%97%AC%EB%A1%A0%EC%A1%B0%EC%82%AC"

### 1.1.2. 표 긁어오기
Sys.setlocale("LC_ALL", "C")
[1] "C"
resp <- read_html(namu_url)
# html_nodes(resp, "table")

seoul_tbl <- resp %>% 
  html_nodes(xpath='/html/body/div[2]/article/div[3]/div/div[9]/div/table') %>% 
  .[[1]] %>% 
  html_table(fill = TRUE)

Sys.setlocale("LC_ALL", "Korean")
[1] "LC_COLLATE=Korean_Korea.949;LC_CTYPE=Korean_Korea.949;LC_MONETARY=Korean_Korea.949;LC_NUMERIC=C;LC_TIME=Korean_Korea.949"
### 1.1.3. 데이터 정제
row_number <- which(grepl("4월 30일~5월 1일", seoul_tbl$X2))

seoul_df <- seoul_tbl %>% 
  filter(row_number() >= row_number -1 ) %>% 
  select(1:5) %>% 
  rename(기관=X1, 날짜=X2, 박원순=X3, 김문수=X4, 안철수=X5) %>% 
  filter(!str_detect(박원순,"박원순")) %>% 
  mutate(박원순 = str_replace_all(박원순, "%", "") %>% as.numeric,
            김문수 = str_replace_all(김문수, "%", "") %>% as.numeric,
            안철수 = str_replace_all(안철수, "%", "") %>% as.numeric) %>% 
  separate(날짜, into=c("시작일", "종료일"), sep="~") %>% 
  separate(시작일, into=c("월", "일"), sep=" ") %>% 
  mutate(월 = str_extract(월, "[0-9]+"),
         일 = str_extract(일, "[0-9]+"))  %>% 
  mutate(조사일 = ymd(str_c("2018-", 월, "-", 일))) %>% 
  select(기관, 조사일, 박원순, 김문수, 안철수) %>% 
  mutate(기관 = str_replace_all(기관, "\\(주\\)", "")) %>% 
  mutate(기관 = str_extract_all(기관, "[가-흫]+")) %>% 
  mutate(시도지사="서울시장")

DT::datatable(seoul_df)

2.2 경기지사

경기지사는 민주당 이재명, 자한당 남경필, 바른미래 김영환 후보가 여론조사에 이름을 올리고 있다.

## 1.2. 경기지사 -----------------------
### 1.2.1. URL 

### 1.1.2. 표 긁어오기
Sys.setlocale("LC_ALL", "C")
[1] "C"
resp <- read_html(namu_url)
# html_nodes(resp, "table")

gg_tbl <- resp %>% 
  html_nodes(xpath='/html/body/div[2]/article/div[3]/div/div[14]/div/table') %>% 
  .[[1]] %>% 
  html_table(fill = TRUE)

Sys.setlocale("LC_ALL", "Korean")
[1] "LC_COLLATE=Korean_Korea.949;LC_CTYPE=Korean_Korea.949;LC_MONETARY=Korean_Korea.949;LC_NUMERIC=C;LC_TIME=Korean_Korea.949"
### 1.1.3. 데이터 정제
gg_row_number <- which(grepl("4월 21~22일", gg_tbl$X2))

gg_df <- gg_tbl %>% 
  filter(row_number() >= gg_row_number -1 ) %>% 
  select(c(1,2,3,7,9)) %>% 
  rename(기관=X1, 날짜=X2, 이재명=X3, 남경필=X7, 김영환=X9) %>% 
  filter(!str_detect(이재명,"이재명")) %>% 
  mutate(이재명 = str_replace_all(이재명, "%", "") %>% as.numeric,
            남경필 = str_replace_all(남경필, "%", "") %>% as.numeric,
            김영환 = str_replace_all(김영환, "%", "") %>% as.numeric) %>% 
  separate(날짜, into=c("시작일", "종료일"), sep="~") %>% 
  separate(시작일, into=c("월", "일"), sep=" ") %>% 
  mutate(월 = str_extract(월, "[0-9]+"),
          일 = str_extract(일, "[0-9]+"))  %>% 
  mutate(조사일 = ymd(str_c("2018-", 월, "-", 일))) %>% 
  select(기관, 조사일, 이재명, 남경필, 김영환) %>% 
  mutate(기관 = str_replace_all(기관, "\\(주\\)", "")) %>% 
  mutate(기관 = str_extract_all(기관, "[가-흫]+")) %>% 
  mutate(시도지사="경기지사")

DT::datatable(gg_df)

2.3 인천시장

인천시장은 민주당 박남춘, 자한당 유정복, 바른미래 문병호 후보가 여론조사에 이름을 올리고 있다.

## 1.3. 인천시장 -----------------------
### 1.3.1. URL 

### 1.3.2. 표 긁어오기
Sys.setlocale("LC_ALL", "C")
[1] "C"
resp <- read_html(namu_url)

incheon_tbl <- resp %>% 
  html_nodes(xpath='/html/body/div[2]/article/div[3]/div/div[19]/div/table') %>% 
  .[[1]] %>% 
  html_table(fill = TRUE)

Sys.setlocale("LC_ALL", "Korean")
[1] "LC_COLLATE=Korean_Korea.949;LC_CTYPE=Korean_Korea.949;LC_MONETARY=Korean_Korea.949;LC_NUMERIC=C;LC_TIME=Korean_Korea.949"
### 1.3.3. 데이터 정제
incheon_row_number <- which(grepl("4월 30~5월 1일", incheon_tbl$X2))

incheon_df <- incheon_tbl %>% 
  filter(row_number() >= incheon_row_number -1 ) %>% 
  select(c(1,2,7,8,9)) %>% 
  rename(기관=X1, 날짜=X2, 박남춘=X7, 유정복=X8, 문병호=X9) %>% 
  filter(!str_detect(박남춘,"박남춘")) %>% 
  mutate(박남춘 = str_replace_all(박남춘, "%", "") %>% as.numeric,
            유정복 = str_replace_all(유정복, "%", "") %>% as.numeric,
            문병호 = str_replace_all(문병호, "%", "") %>% as.numeric) %>% 
  separate(날짜, into=c("시작일", "종료일"), sep="~") %>% 
  separate(시작일, into=c("월", "일"), sep=" ") %>% 
  mutate(월 = str_extract(월, "[0-9]+"),
          일 = str_extract(일, "[0-9]+"))  %>% 
  mutate(조사일 = ymd(str_c("2018-", 월, "-", 일))) %>% 
  select(기관, 조사일, 박남춘, 유정복, 문병호) %>% 
  mutate(기관 = str_replace_all(기관, "\\(주\\)", "")) %>% 
  mutate(기관 = str_extract_all(기관, "[가-흫]+")) %>% 
  mutate(시도지사="인천시장")

DT::datatable(incheon_df)

2.4 경남지사

경남지사는 민주당 김경수 후보가 드루킹 사건에 연루되어 많은 관심이 모여지는 선거다. 현재, 경남지사는 민주당 김경수, 자한당 김태호, 바른미래 김유근 후보가 여론조사에 이름을 올리고 있다.

## 1.17. 경상남도 -----------------------
### 1.17.1. URL 

### 1.17.2. 표 긁어오기
Sys.setlocale("LC_ALL", "C")
[1] "C"
resp <- read_html(namu_url)

gn_tbl <- resp %>% 
  html_nodes(xpath='/html/body/div[2]/article/div[3]/div/div[80]/div/table') %>% 
  .[[1]] %>% 
  html_table(fill = TRUE)

Sys.setlocale("LC_ALL", "Korean")
[1] "LC_COLLATE=Korean_Korea.949;LC_CTYPE=Korean_Korea.949;LC_MONETARY=Korean_Korea.949;LC_NUMERIC=C;LC_TIME=Korean_Korea.949"
### 1.3.3. 데이터 정제
gn_row_number <- which(grepl("4월 30~5월 1일", gn_tbl$X2))

gn_df <- gn_tbl %>% 
  filter(row_number() >= gn_row_number -1 ) %>% 
  select(c(1,2,3,6,9)) %>% 
  rename(기관=X1, 날짜=X2, 김경수=X3, 김태호=X6, 김유근=X9) %>% 
  filter(!str_detect(김경수,"김경수")) %>% 
  mutate(김경수 = str_replace_all(김경수, "%", "") %>% as.numeric,
            김태호 = str_replace_all(김태호, "%", "") %>% as.numeric,
            김유근 = str_replace_all(김유근, "%", "") %>% as.numeric) %>% 
  separate(날짜, into=c("시작일", "종료일"), sep="~") %>% 
  separate(시작일, into=c("월", "일"), sep=" ") %>% 
  mutate(월 = str_extract(월, "[0-9]+"),
          일 = str_extract(일, "[0-9]+"))  %>% 
  mutate(조사일 = ymd(str_c("2018-", 월, "-", 일))) %>% 
  select(기관, 조사일, 김경수, 김태호, 김유근) %>% 
  mutate(기관 = str_replace_all(기관, "\\(주\\)", "")) %>% 
  mutate(기관 = str_extract_all(기관, "[가-흫]+")) %>% 
  mutate(시도지사="경남지사")

DT::datatable(gn_df)

3 격전지 판세

각당별로 경선을 통해서 후보가 확정됨에 따라 대진표가 윤곽이 서서히 나타나기 전부터, 시점별로 여론조사 기관에서 여론조사를 실시하여 이를 시각적으로 표현하게 되면 나름대로 현재 주요 격전지 판세를 유추할 수 있을 것으로 판단된다.

# 2. 데이터 정제 -----
## 2.1. 데이터 변환 
seoul_lng_df <- seoul_df %>% na.omit %>% 
  gather(후보, 지지율, -기관, - 조사일, -시도지사)

gg_lng_df <- gg_df %>% na.omit %>% 
  gather(후보, 지지율, -기관, - 조사일, -시도지사)

incheon_lng_df <- incheon_df %>% na.omit %>% 
  gather(후보, 지지율, -기관, - 조사일, -시도지사)

gn_lng_df <- gn_df %>% na.omit %>% 
  gather(후보, 지지율, -기관, - 조사일, -시도지사)

## 2.2. 데이터 취합 + 정당
local_df <- bind_rows(seoul_lng_df, gg_lng_df) %>% 
  bind_rows(incheon_lng_df) %>% 
  bind_rows(gn_lng_df) %>% 
  mutate(정당 = case_when(후보 %in% c("박원순", "이재명", "박남춘", "김경수") ~ "민주당",
                          후보 %in% c("김문수", "유정복", "남경필", "김태호") ~ "자한당",
                          후보 %in% c("안철수", "문병호", "김영환", "김유근") ~ "바른미래")) %>% 
  mutate(정당 = fct_relevel(정당, "민주당", "자한당", "바른미래"))

# 3. 시각화 -----

local_g <- local_df %>% 
  ggplot(aes(x=조사일, y=지지율, color=정당, group=정당,
             text = paste('조사일 :', 조사일, "\n",
                          '지지율:', str_c(지지율,"%"), "\n",
                          '정당: ', 정당, "\n",
                          '조사기관:', 기관))) +
    geom_point() +
    geom_smooth(se=FALSE) +
    geom_line() +
    facet_wrap(~시도지사) +
    scale_color_manual(values = c("blue", "red", "cyan")) +
    scale_x_date(date_labels = "%m-%d") +
    labs(x="", y="지지율") +
    theme_minimal(base_family = "NanumGothic") +
    theme(strip.text = element_text(face="bold", size=12))

ggplotly(local_g, tooltip = "text")