역대지방선거 광역단체장에 대한 역대 지방선거(제5회, 제6회)의 더불어민주당, 자유한국당 양당의 득표율 추이를 비교하고, 제6회 지방선거와 제7회 지방선거 여론조사를 현재시점(2018-05-22) 기준 비교한다.
나무위키 제5회 전국동시지방선거 웹사이트에서 광역단체장 선거결과를 받아온다.
함수형 프로그래밍을 통해 각시도를 키값으로 삼아 list column 티블 자료구조로 구현한 후 후속 데이터 분석을 위해서 데이터프레임으로 변환시킨다.
# 0. 환경설정 -----
library(tidyverse)
library(rvest)
library(glue)
library(plotrix)
library(lubridate)
# 1. 데이터: 제 5 회 지방선거 -----
## 1.1. 제 5 회 지방선거 -----
crawl_five_data <- function(index_id) {
Sys.setlocale("LC_ALL", "C")
five_url <- "https://namu.wiki/w/%EC%A0%9C5%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"
tmp_tbl <- read_html(five_url) %>%
html_nodes('table') %>%
.[[index_id]] %>%
html_table(fill=TRUE)
Sys.setlocale("LC_ALL", "Korean")
sido_name <- tmp_tbl$X1[1]
names(tmp_tbl) <- tmp_tbl[2,]
res_tbl <- tmp_tbl %>%
filter(str_detect(기호, "[0-9]+")) %>%
mutate(시도명 = sido_name)
res_list <- list(sido=sido_name, data=res_tbl)
return(res_list)
}
five_sido_list <- vector("list", length=16)
for(i in 1:length(five_sido_list)) {
five_sido_list[[i]] <- crawl_five_data(10+i)
}
## 1.2. 데이터 정제 -----
five_df <- tibble(
sido = map_chr(five_sido_list, ~.$sido),
data = map(five_sido_list, ~.$data)
)
five_df <- map_df(five_df$data, bind_rows)
## 1.3. 데이터 내보내기 -----
five_df <- five_df %>% as_tibble() %>%
mutate(득표수 = str_replace_all(득표수, ",", "") %>% as.integer,
득표율 = str_replace(득표율, "%", "") %>% as.numeric,
순위 = as.integer(순위))
five_df %>%
select(시도명, everything()) %>%
DT::datatable()
나무위키 제6회 전국동시지방선거 웹사이트에서 광역단체장 선거결과를 받아온다.
동일한 방식으로 함수형 프로그래밍을 통해 각시도를 키값으로 삼아 list column 티블 자료구조로 구현한 후 후속 데이터 분석을 위해서 데이터프레임으로 변환시킨다.
# 2. 데이터: 제 6 회 지방선거 -----
## 2.1. 제 6 회 지방선거 -----
crawl_six_data <- function(index_id) {
Sys.setlocale("LC_ALL", "C")
six_url <- "https://namu.wiki/w/%EC%A0%9C6%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/%EA%B4%91%EC%97%AD%EC%9E%90%EC%B9%98%EB%8B%A8%EC%B2%B4%EC%9E%A5"
tmp_tbl <- read_html(six_url) %>%
html_nodes('table') %>%
.[[index_id]] %>%
html_table(fill=TRUE)
Sys.setlocale("LC_ALL", "Korean")
tmp_tbl
sido_name <- tmp_tbl$X1[1]
names(tmp_tbl) <- tmp_tbl[2,]
res_tbl <- tmp_tbl %>%
filter(str_detect(기호, "[0-9]+")) %>%
mutate(시도명 = sido_name)
res_list <- list(sido=sido_name, data=res_tbl)
return(res_list)
}
six_sido_list <- vector("list", length=17)
for(i in 1:length(six_sido_list)) {
six_sido_list[[i]] <- crawl_six_data(2+i)
}
## 2.2. 데이터 정제 -----
six_df <- tibble(
sido = map_chr(six_sido_list, ~.$sido),
data = map(six_sido_list, ~.$data)
)
six_df <- map_df(six_df$data, bind_rows)
## 1.3. 데이터 내보내기 -----
six_df <- six_df %>% as_tibble() %>%
mutate(득표수 = str_replace_all(득표수, ",", "") %>% as.integer,
득표율 = str_replace(득표율, "%", "") %>% as.numeric,
순위 = as.integer(순위))
six_df %>%
select(시도명, everything()) %>%
DT::datatable()
Slopegraph를 통해서 제5회 지방선거와 제6회 지방선거 전후변화를 시각적으로 표현하도록 적절한 형태로 데이터를 변환한다. 특히, 간결한 시작적 내용 전달을 위해서 시도명과 득표율을 단순화시킨다.
## 1.2. 데이터 병합: 제 5,6 회 지방선거 -----
five_df <- five_df %>%
mutate(선수="제5회")
six_df <- six_df %>%
mutate(선수="제6회")
local_df <- bind_rows(five_df, six_df)
names(local_df) <- c("기호", "후보명", "정당", "득표수", "득표율", "순위", "당선여부", "시도명", "선수")
# 2. 데이터 정제 -----
local_df <- local_df %>%
filter(정당 !="평화민주당") %>%
mutate(신정당 = case_when(str_detect(정당, "새누리") ~ "자한당",
str_detect(정당, "한나라") ~ "자한당",
str_detect(정당, "새정치민주연합") ~ "더민주",
str_detect(정당, "민주당") ~ "더민주",
TRUE ~ "기타")) %>%
as_tibble() %>%
filter(!str_detect(신정당, "기타")) %>%
mutate(시도명 = case_when(
str_detect(시도명, "서울특별시장") ~ "서울",
str_detect(시도명, "인천광역시장") ~ "인천",
str_detect(시도명, "경기도지사") ~ "경기",
str_detect(시도명, "강원도지사") ~ "강원",
str_detect(시도명, "대전광역시장") ~ "대전",
str_detect(시도명, "세종특별자치시장") ~ "세종",
str_detect(시도명, "충청남도지사") ~ "충남",
str_detect(시도명, "충청북도지사") ~ "충북",
str_detect(시도명, "광주광역시장") ~ "광주",
str_detect(시도명, "전라남도지사") ~ "전남",
str_detect(시도명, "전라북도지사") ~ "전북",
str_detect(시도명, "부산광역시장") ~ "부산",
str_detect(시도명, "대구광역시장") ~ "대구",
str_detect(시도명, "울산광역시장") ~ "울산",
str_detect(시도명, "경상남도지사") ~ "경남",
str_detect(시도명, "경상북도지사") ~ "경북",
str_detect(시도명, "제주특별자치도지사") ~ "제주"))
local_viz_df <- local_df %>%
mutate(득표수 = str_replace_all(득표수, ",", "") %>% as.integer,
득표율 = str_replace(득표율, "%", "") %>% as.numeric,
순위 = as.integer(순위))
DT::datatable(local_viz_df)
Slopegraph를 적용해서 더불어 민주당과 자유한국당으로 나눠서 시도별로 제5회, 제6회 지방선거 사이 변화한 정치지형변화를 살펴본다.
bumpchart2<-function (y, top.labels = colnames(y), labels = rep(rownames(y),2),
rank = TRUE, mar = c(2, 8, 5, 8), pch = 19, col = par("fg"),
lty = 1, lwd = 1, arrows = FALSE, ...) {
if (missing(y)) stop("Usage: bumpchart(y,top.labels,labels,...)")
ydim <- dim(y)
if (is.null(ydim)) stop("y must be a matrix or data frame")
oldmar <- par("mar")
par(mar = mar)
if (rank)
y <- apply(y, 2, rank)
labels <- rev(labels)
pch = rev(pch)
col = rev(col)
lty = rev(lty)
lwd = rev(lwd)
y <- apply(y, 2, rev)
if (arrows) {
matplot(t(y), ylab = "", type = "p", pch = pch, col = col,
axes = FALSE)
for (row in 1:(ydim[2] - 1)) p2p_arrows(rep(row, ydim[1]),
y[, row], rep(row + 1, ydim[1]), y[, row + 1], col = col,
lty = lty, lwd = lwd, ...)
}
else matplot(t(y), ylab = "", type = "b", pch = pch, col = col,
lty = lty, lwd = lwd, axes = FALSE, ...)
par(xpd = TRUE)
xylim <- par("usr")
minspacing <- strheight("M") * 1.5
text(1:ydim[2], xylim[4], top.labels)
text(xylim[1], y[,1], labels[(ydim[1]+1):(2*ydim[1])], adj = 1)
# cat(y[,1],"\n")
text(xylim[2], y[,2], labels[1:ydim[1]], adj = 0)
# cat(y[,2],"\n")
par(mar = oldmar, xpd = FALSE)
}
# 3. 데이터 시각화 -----
## 3.1. 민주당 ----
local_viz_minju_df <- local_viz_df %>%
select(시도명, 신정당, 득표율, 선수) %>%
mutate(득표율 = round(득표율,1)) %>%
spread(선수, 득표율) %>%
filter(신정당 == "더민주") %>%
as.data.frame() %>%
column_to_rownames(var="시도명") %>%
select(-신정당)
bumpchart2(local_viz_minju_df, mar=c(6, 12, 6, 12),col=RColorBrewer::brewer.pal(12, "Set3"),
labels=c(paste(rownames(local_viz_minju_df), local_viz_minju_df[,1], sep=" "),
paste(local_viz_minju_df[,2], rownames(local_viz_minju_df), sep=" ")),rank=FALSE,lwd=3,
top.labels = c("제5회", "제6회"))
title(main="[민주당] 제5,6회 지방선거 비교", line=1.5, col.main="navy blue")
## 3.2. 자한당 ----
local_viz_free_df <- local_viz_df %>%
select(시도명, 신정당, 득표율, 선수) %>%
mutate(득표율 = round(득표율,1)) %>%
spread(선수, 득표율) %>%
filter(신정당 == "자한당") %>%
as.data.frame() %>%
column_to_rownames(var="시도명") %>%
select(-신정당)
bumpchart2(local_viz_free_df, mar=c(6, 12, 6, 12),col=RColorBrewer::brewer.pal(12, "Set3"),
labels=c(paste(rownames(local_viz_free_df), local_viz_free_df[,1], sep=" "),
paste(local_viz_free_df[,2], rownames(local_viz_free_df), sep=" ")),rank=FALSE,lwd=3,
top.labels = c("제5회", "제6회"))
title(main="[자한당] 제5,6회 지방선거 비교", line=1.5, col.main="navy blue")
제6회 지방선거 결과와 제7회 지방선거 가장 최근 여론조사 전후변화를 시각적으로 표현하도록 적절한 형태로 데이터를 변환한다. 특히, 간결한 시작적 내용 전달을 위해서 시도명과 득표율을 단순화시킨다.
# 1. 데이터 -----
## 1.1. 데이터 가져오기:제6회 지방선거 결과 -----
names(six_df) <- c("기호", "후보명", "정당", "득표수", "득표율", "순위", "당선여부", "시도명")
## 1.2. 데이터 가져오기:제7회 지방선거 여론조사 -----
seven_df <- read_rds("data/sido_survey_df.rds")
names(seven_df) <- c("조사 의뢰", "조사 기관", "응답 인원", "더불어민주당", "자유한국당", "바른미래당",
"정의당", "기타·무응답", "참고", "조사일", "시도명", "민주평화당", "무소속")
seven_df <- seven_df %>%
mutate(무소속 = str_replace_all(무소속, "%", "") %>% as.numeric,
민주평화당 = str_replace_all(민주평화당, "%", "") %>% as.numeric) %>%
group_by(시도명) %>%
arrange(조사일) %>%
mutate(조사일_id = row_number()) %>%
filter(조사일_id == max(조사일_id)) %>%
select(시도명, contains("당"), contains("무소속")) %>%
ungroup() %>%
gather(정당, 득표율, -시도명) %>%
mutate(득표율 = round(as.numeric(득표율),1))
## 1.3. 데이터 병합 -----
six_df <- six_df %>%
mutate(선수="제6회") %>%
select(선수, 시도명, 정당, 득표율) %>%
as_tibble() %>%
mutate(득표율 = str_replace_all(득표율, "%", "") %>% as.numeric %>% round(1)) %>%
filter(str_detect(정당, pattern="새누리당|새정치민주연합"))
seven_df <- seven_df %>%
mutate(선수="제7회") %>%
select(선수, 시도명, 정당, 득표율) %>%
filter(str_detect(정당, pattern="더불어민주당|자유한국당"))
local_now_df <- bind_rows(six_df, seven_df)
# 2. 데이터 정제 -----
local_now_df <- local_now_df %>%
mutate(시도명 = case_when(
str_detect(시도명, "서울특별시장") ~ "서울",
str_detect(시도명, "인천광역시장") ~ "인천",
str_detect(시도명, "경기도지사") ~ "경기",
str_detect(시도명, "강원도지사") ~ "강원",
str_detect(시도명, "대전광역시장") ~ "대전",
str_detect(시도명, "세종특별자치시장") ~ "세종",
str_detect(시도명, "충청남도지사") ~ "충남",
str_detect(시도명, "충청북도지사") ~ "충북",
str_detect(시도명, "광주광역시장") ~ "광주",
str_detect(시도명, "전라남도지사") ~ "전남",
str_detect(시도명, "전라북도지사") ~ "전북",
str_detect(시도명, "부산광역시장") ~ "부산",
str_detect(시도명, "대구광역시장") ~ "대구",
str_detect(시도명, "울산광역시장") ~ "울산",
str_detect(시도명, "경상남도지사") ~ "경남",
str_detect(시도명, "경상북도지사") ~ "경북",
str_detect(시도명, "제주특별자치도지사") ~ "제주"))
DT::datatable(local_now_df)
# 3. 데이터 시각화 -----
bumpchart2<-function (y, top.labels = colnames(y), labels = rep(rownames(y),2),
rank = TRUE, mar = c(2, 8, 5, 8), pch = 19, col = par("fg"),
lty = 1, lwd = 1, arrows = FALSE, ...) {
if (missing(y)) stop("Usage: bumpchart(y,top.labels,labels,...)")
ydim <- dim(y)
if (is.null(ydim)) stop("y must be a matrix or data frame")
oldmar <- par("mar")
par(mar = mar)
if (rank)
y <- apply(y, 2, rank)
labels <- rev(labels)
pch = rev(pch)
col = rev(col)
lty = rev(lty)
lwd = rev(lwd)
y <- apply(y, 2, rev)
if (arrows) {
matplot(t(y), ylab = "", type = "p", pch = pch, col = col,
axes = FALSE)
for (row in 1:(ydim[2] - 1)) p2p_arrows(rep(row, ydim[1]),
y[, row], rep(row + 1, ydim[1]), y[, row + 1], col = col,
lty = lty, lwd = lwd, ...)
}
else matplot(t(y), ylab = "", type = "b", pch = pch, col = col,
lty = lty, lwd = lwd, axes = FALSE, ...)
par(xpd = TRUE)
xylim <- par("usr")
minspacing <- strheight("M") * 1.5
text(1:ydim[2], xylim[4], top.labels)
text(xylim[1], y[,1], labels[(ydim[1]+1):(2*ydim[1])], adj = 1)
# cat(y[,1],"\n")
text(xylim[2], y[,2], labels[1:ydim[1]], adj = 0)
# cat(y[,2],"\n")
par(mar = oldmar, xpd = FALSE)
}
## 3.1. 민주당 ----
local_now_minju_df <- local_now_df %>%
filter(str_detect(정당, "새정치민주연합|더불어민주당")) %>%
select(-정당) %>%
spread(선수, 득표율) %>%
as.data.frame() %>%
column_to_rownames(var="시도명")
bumpchart2(local_now_minju_df, mar=c(6, 12, 6, 12),col=RColorBrewer::brewer.pal(12, "Set3"),
labels=c(paste(rownames(local_now_minju_df), local_now_minju_df[,1], sep=" "),
paste(local_now_minju_df[,2], rownames(local_now_minju_df), sep=" ")),rank=FALSE,lwd=3,
top.labels = c("제6회", "제7회"))
title(main="[민주당] 제6,7회 지방선거 비교", line=1.5, col.main="navy blue")
## 3.2. 자유한국당 ----
local_now_free_df <- local_now_df %>%
filter(str_detect(정당, "새누리당|자유한국당")) %>%
select(-정당) %>%
spread(선수, 득표율) %>%
as.data.frame() %>%
column_to_rownames(var="시도명")
bumpchart2(local_now_free_df, mar=c(6, 12, 6, 12),col=RColorBrewer::brewer.pal(12, "Set3"),
labels=c(paste(rownames(local_now_free_df), local_now_free_df[,1], sep=" "),
paste(local_now_free_df[,2], rownames(local_now_free_df), sep=" ")),rank=FALSE,lwd=3,
top.labels = c("제6회", "제7회"))
title(main="[자한당] 제6,7회 지방선거 비교", line=1.5, col.main="navy blue")