제20대 vs 제21대

제20대 총선과 제21대 총선 차이를 살펴보자.

저자
소속

1 데이터셋

1.1 제20대 총선

코드
library(tidyverse)
library(testthat)
library(krvote)

vote_2016_tbl <- krvote::general_2016 |> 
  unnest(data) |> 
  mutate(구분 = case_when(str_detect(구분, "[가-힣]+") ~ 구분,
                         TRUE ~ iconv(구분, "CP949", "UTF-8"))) |> 
  filter(!구분 %in% c("선거인수", "투표수", "무표투표수", "기권수")) |> 
  mutate(정당 = case_when(str_detect(구분, "더불어민주당") ~ "민주당",
                          str_detect(구분, "새누리당") ~ "국민의힘",
                          구분 == "계" ~ "합계",
                          TRUE ~ "그외정당")) |>
  separate(선거구, into = c("선거구", "시군구명"), sep = "_") |> 
  group_by(시도, 선거구, 정당) |> 
  summarise(득표수 = sum(사람수)) |> 
  ungroup() |> 
  pivot_wider(names_from = 정당, values_from = 득표수) |> 
  mutate(국힘_득표율 = 국민의힘 / 합계,
         민주_득표율 = 민주당 / 합계)  |> 
  mutate(차이 = 민주_득표율 - 국힘_득표율) |> 
  mutate(권역 = case_when(시도 %in% c("서울", "인천", "경기") ~ "수도권",
                        시도 %in% c("부산", "울산", "경남") ~ "부울경",
                        시도 %in% c("대구", "경북") ~ "대구경북",
                        시도 %in% c("강원", "제주") ~ "강원제주",
                        시도 %in% c("대전", "충남", "충북", "세종") ~ "대전충청세종",
                        시도 %in% c("광주", "전남", "전북") ~ "광주전라")) |> 
  mutate(선거 = "제20대")

1.2 제21대 총선

코드
vote_2020_tbl <- krvote::general_2020 |> 
  unnest(data) |> 
  mutate(구분 = case_when(str_detect(구분, "[가-힣]+") ~ 구분,
                         TRUE ~ iconv(구분, "CP949", "UTF-8"))) |> 
  filter(!구분 %in% c("선거인수", "투표수", "무표투표수", "기권수")) |> 
  mutate(정당 = case_when(str_detect(구분, "더불어민주당") ~ "민주당",
                          str_detect(구분, "미래통합당") ~ "국민의힘",
                          구분 == "계" ~ "합계",
                          TRUE ~ "그외정당")) |>
  separate(선거구, into = c("선거구", "시군구명"), sep = "_") |> 
  group_by(시도, 선거구, 정당) |> 
  summarise(득표수 = sum(사람수)) |> 
  ungroup() |> 
  pivot_wider(names_from = 정당, values_from = 득표수) |> 
  mutate(국힘_득표율 = 국민의힘 / 합계,
         민주_득표율 = 민주당 / 합계)  |> 
  mutate(차이 = 민주_득표율 - 국힘_득표율) |> 
  mutate(권역 = case_when(시도 %in% c("서울", "인천", "경기") ~ "수도권",
                        시도 %in% c("부산", "울산", "경남") ~ "부울경",
                        시도 %in% c("대구", "경북") ~ "대구경북",
                        시도 %in% c("강원", "제주") ~ "강원제주",
                        시도 %in% c("대전", "충남", "충북", "세종") ~ "대전충청세종",
                        시도 %in% c("광주", "전남", "전북") ~ "광주전라")) |> 
    mutate(선거 = "제21대")

1.3 결합

코드
vote_tbl <- bind_rows(vote_2016_tbl, vote_2020_tbl)

1.4 산점도

코드
vote_diff <- full_join(vote_2016_tbl |> select(권역, 시도, 선거구, 득표차20 = 차이), 
          vote_2020_tbl |> select(권역, 시도, 선거구, 득표차21 = 차이), 
          by = c("시도", "선거구", "권역")) 

vote_diff |>
  ggplot(aes(x = 득표차20, y = 득표차21, color = 권역)) +
    geom_point() +
    geom_abline(intercept = 0, slope = 1) 

2 시각화

2.1 총선전체

코드
library(ggrepel)

gangseo_tbl <- vote_tbl |> 
  filter(시도 == "서울",
         str_detect(선거구, "강서구(갑|을|병)"))  
  

full_diff_g <- vote_tbl |>
  ggplot(aes(x = 차이)) +
    geom_histogram(bins = 20, fill = "skyblue", color = "white") +
    geom_density(aes(y = ..density.. * 0.03 * (nrow(vote_tbl)))) +  
    facet_wrap(~선거, ncol = 1) +
    theme_korean() +
    theme(legend.position = "none",
          strip.text = element_text(size = 15)) +
    geom_vline(xintercept = 0, color = "red", size = 0.3, linetype = 2) +
    labs(title = "민주당과 국민의힘 득표율 차이 분포", 
         subtitle = "2016년과 2020년 총선 민주당과 국민의힘 득표율 차이 분포", 
         x = "민주당 - 국민의힘 득표율 차이", 
         y = "선거구수") +
    scale_x_continuous(breaks = seq(-1, 1, 0.2), 
                       labels = scales::percent_format(accuracy = 1)) +
    geom_vline(data = gangseo_tbl, aes(xintercept = 차이, color = 선거구)) +
    geom_text_repel(data = gangseo_tbl, 
              aes(x = 차이, y = 35, label = 선거구, color = 선거구, size = 1.5))

full_diff_g

코드

ragg::agg_jpeg("images/총선득표차_분포.jpeg",
               width = 10, height = 7, units = "in", res = 600)
full_diff_g
dev.off()
#> png 
#>   2

2.2 군역별

코드


region_diff_g <- vote_tbl |>
  mutate(권역 = case_when(시도 %in% c("서울", "인천", "경기") ~ "수도권",
                        시도 %in% c("부산", "울산", "경남") ~ "부울경",
                        시도 %in% c("대구", "경북", "광주", "전남", "전북") ~ "광주전라/대구경북",
                        시도 %in% c("대전", "충남", "충북", "세종", "강원", "제주") ~ "대전충청세종강원제주")) |>   
  mutate(권역 = factor(권역, levels = c("수도권", "부울경", "대전충청세종강원제주", "광주전라/대구경북"))) |>
  ggplot(aes(x = 차이)) +
  geom_histogram(bins = 20, fill = "skyblue", color = "white") +
  # geom_density(aes(y = ..density.. * 0.02 * (nrow(vote_tbl)))) +  
  facet_grid(권역~선거, scales = "fixed") +
  theme_korean() +
  theme(legend.position = "none",
        strip.text = element_text(size = 10)) +
  geom_vline(xintercept = 0, color = "red", size = 0.3, linetype = 2) +
  labs(title = "권역별 민주당과 국민의힘 득표율 차이 분포", 
       subtitle = "2016년과 2020년 총선 민주당과 국민의힘 득표율 차이 분포", 
       x = "민주당 - 국민의힘 득표율 차이", 
       y = "선거구수") +
  scale_x_continuous(breaks = seq(-1, 1, 0.2), 
                     labels = scales::percent_format(accuracy = 1)) +
  geom_vline(data = gangseo_tbl, aes(xintercept = 차이, color = 선거구)) +
  geom_text_repel(data = gangseo_tbl, 
                  aes(x = 차이, y = 35, label = 선거구, color = 선거구, size = 1.0))

region_diff_g

코드

ragg::agg_jpeg("images/총선득표차_권역별분포.jpeg",
               width = 10, height = 7, units = "in", res = 600)
region_diff_g
dev.off()
#> png 
#>   2