1 서울 판세분석

1.1 데이터 정제

여론조사 데이터에서 지역구를 끌어오지 못해서 다른 곳에서 후보자와 선거구가 붙어있는 데이터에서 이를 결합시켜 선거구 정보를 붙인다.

seoul_full_df <- read_rds("data/seoul_full_df.rds")

## 데이터 전처리
seoul_poll_df <- seoul_full_df %>% 
  mutate(날짜 = str_extract(조사일자, "[0-9]{4}년\\s?[0-9]{1,2}월\\s?[0-9]{1,2}")) %>% 
  mutate(날짜 = str_replace(날짜, "년 ", "-") %>% str_replace("월 ", "-")) %>% 
  mutate(날짜 = lubridate::ymd(날짜)) %>% 
  mutate(조사업체 = str_remove(조사업체, "\\s+조사\\[[0-9].*\\]$")) %>% 
  select(날짜, 정당, 후보자명, 지지율, 조사업체) %>% 
  mutate(지지율 = parse_number(지지율))

## 후보와 선거구 데이터 
# guess_encoding("data/candidate_253_df.rds")[1,1] %>% as.character
candidate_253_df <- read_rds("data/candidate_253_df.rds")
names(candidate_253_df) <- iconv(names(candidate_253_df), from="euc-kr", to="utf-8")

seoul_precinct_df <- candidate_253_df %>% 
  mutate(시도명 = iconv(시도명, from="euc-kr", to="utf-8")) %>% 
  filter(str_detect(시도명, "서울"),
         str_detect(정당명, "더불어민주당")) %>% 
  select(선거구명, 성명) %>% 
  separate(성명, into=c("후보자명", "한문"), sep="\\(") %>% 
  select(선거구명, 후보자명)

## 결합
seoul_latest_df <- left_join(seoul_poll_df, seoul_precinct_df) %>% 
  mutate(선거구명 = zoo::na.locf(선거구명)) %>% 
  group_by(선거구명) %>% 
  filter(날짜 == max(날짜)) %>% 
  ungroup()

seoul_latest_df
# A tibble: 48 x 6
   날짜       정당   후보자명 지지율 조사업체     선거구명  
   <date>     <chr>  <chr>     <dbl> <chr>        <chr>     
 1 2020-03-31 민주   이낙연     51   피플네트웍스 종로구    
 2 2020-03-31 통합   황교안     39   피플네트웍스 종로구    
 3 2020-03-31 공화   한민호      1.6 피플네트웍스 종로구    
 4 2020-03-31 민중   오인환      0.7 피플네트웍스 종로구    
 5 2020-03-31 무당층 무당층      5.4 피플네트웍스 종로구    
 6 2020-03-28 민주   고민정     47.1 리얼미터     광진구을  
 7 2020-03-28 통합   오세훈     43.3 리얼미터     광진구을  
 8 2020-03-28 무당층 무당층      8.1 리얼미터     광진구을  
 9 2020-03-29 민주   장경태     35.7 한국리서치   동대문구을
10 2020-03-29 통합   이혜훈     32.2 한국리서치   동대문구을
# … with 38 more rows

1.2 판세

선거구별로 가장 지지율이 높은 정당을 뽑아 현재 판세를 분석해 본다.

seoul_latest_df %>% 
  group_by(선거구명) %>% 
  filter(지지율 == max(지지율)) %>% 
  ungroup() %>% 
  count(정당)
# A tibble: 2 x 2
  정당      n
  <chr> <int>
1 민주      7
2 통합      2

1.3 판세 시각화

앞서 나온 분석된 결과를 바탕으로 현재 지지율 1위를 달리고 있는 정당과 후보자를 서울 선거구별로 나눠 시각화한다. 여론조사 선거구를 참조한다.

library(tidyverse)
library(sf)
library(geogrid)
library(tmap)

## 지도 및 서울
precinct <- st_read("data/shapefile/2020_21_elec_253_simple.json")
Reading layer `2020_21_elec_253_simple' from data source `/Users/statkclee/swc/election/data/shapefile/2020_21_elec_253_simple.json' using driver `GeoJSON'
Simple feature collection with 253 features and 4 fields
geometry type:  MULTIPOLYGON
dimension:      XY
bbox:           xmin: 124.6098 ymin: 33.16123 xmax: 130.9175 ymax: 38.61369
epsg (SRID):    4326
proj4string:    +proj=longlat +datum=WGS84 +no_defs
seoul_precinct <- precinct %>% 
  filter(SGG_1 == "서울") %>% 
  mutate(선거구명 = str_extract(SGG_2, "\\s([가-힣].+)$") %>% str_trim())

## 판세 데이터
seoul_situation_df <- seoul_latest_df %>% 
  group_by(선거구명) %>% 
  filter(지지율 == max(지지율)) %>% 
  ungroup() %>% 
  select(선거구명, 정당)

## 데이터 결합
seoul_situation_sf <- seoul_precinct %>% 
  left_join(seoul_situation_df) %>% 
  mutate(colour = case_when(str_detect(정당, "민주") ~"blue",
                           str_detect(정당, "통합") ~"pink",
                           TRUE ~ "white"))

## 육각형 시각화
seoul_precinct_hex <- calculate_grid(shape = seoul_situation_sf, grid_type = "hexagonal", seed = 3)
seoul_precinct_hex_map <- assign_polygons(seoul_situation_sf, seoul_precinct_hex)

## 고고씽

seoul_precinct_hex_plot <- tm_shape(seoul_precinct_hex_map) + 
  tm_polygons(col="colour", palette = "viridis", colorNA="white") +
  tm_text("선거구명", size=0.5) +
  tm_layout(fontfamily="NanumGothic",
            legend.position = c("left","top"),
            legend.show=FALSE)

seoul_precinct_hex_plot