예비 후보자

국회의원 후보자 정보 조회 서비스 API를 통해 후보자를 살펴보자.

저자
소속

1 데이터

공공데이터포털 중앙선거관리위원회 후보자 정보 API 를 통해 당선인 정보를 조회한다. (후보자 정보를 조회 할 수 있는 서비스 이다.(예비후보자 및 후보자 의 성명, 생년월일, 성별 , 선거구, 시도, 학력, 경력, 등록상태 등을 확인 할 수 있는 서비스)

1.1 위키 국회의원 당선인

코드
library(tidyverse)
library(rvest)
library(gt)
library(gtExtras)
library(rvest)

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

precinct_tbl <- total_elected_all |> 
  filter(sgId == "20200415") |> 
  select(result) |> 
  unnest(result) |> 
  select(시도명 = sdName, 선거구명 = sggName)

1.2 당선인 url 추출

코드
election_html <- read_html("https://ko.wikipedia.org/wiki/대한민국_제21대_국회의원_선거")

urls <- election_html %>% 
  html_nodes("#mw-content-text > div.mw-parser-output > table:nth-child(112)") %>% 
  html_nodes("a") %>% 
  html_attr('href')

url_names <- election_html %>% 
  html_nodes("#mw-content-text > div.mw-parser-output > table:nth-child(112)") %>% 
  html_nodes("a") %>% 
  html_text()

url_raw <- tibble(names = url_names,
       url  = urls)

# url_names |> 
#   clipr::write_clip()

url_tbl <- url_raw |> 
  mutate(시도명 = if_else(names %in% 
                         c("서울특별시", "부산광역시", "대구광역시", "인천광역시",
                           "광주광역시", "대전광역시", "울산광역시", "세종특별자치시",
                           "경기도", "강원도", "충청북도", "충청남도", "전라북도", 
                           "전라남도", "경상북도", "경상남도", "제주특별자치도"), names, NA_character_)) |> 
  fill(시도명, .direction = "down") |> 
  select(시도명, 선거구명 = names, url) |> 
  filter(시도명 != 선거구명) |> 
  mutate(url = URLdecode(url))


url_tbl
#> # A tibble: 506 × 3
#>    시도명     선거구명       url                         
#>    <chr>      <chr>          <chr>                       
#>  1 서울특별시 종로구         /wiki/종로구_(1988년_선거구)
#>  2 서울특별시 중구·성동구 갑 /wiki/중구·성동구_갑        
#>  3 서울특별시 중구·성동구 을 /wiki/중구·성동구_을        
#>  4 서울특별시 용산구         /wiki/용산구_(1988년_선거구)
#>  5 서울특별시 광진구 갑      /wiki/광진구_갑             
#>  6 서울특별시 이낙연         /wiki/이낙연                
#>  7 서울특별시 홍익표         /wiki/홍익표_(1967년)       
#>  8 서울특별시 박성준         /wiki/박성준_(정치인)       
#>  9 서울특별시 권영세         /wiki/권영세_(1959년)       
#> 10 서울특별시 전혜숙         /wiki/전혜숙                
#> # ℹ 496 more rows

1.3 당선인 + 선거구

코드
mp_url_tbl <- url_tbl |> 
  mutate(선거구명 = str_remove_all(선거구명, "[\\s+|·]")) |> 
  anti_join(precinct_tbl, by = c("시도명", "선거구명")) |> 
  mutate(url = str_glue("https://ko.wikipedia.org{url}")) |> 
  rename(당선인 = 선거구명)
    

mp_url_tbl |> 
  mutate(
      link = glue::glue("[website]({url})"),
      link = map(link, gt::md)) |> 
  select(시도명, 당선인, link) |>
  gt(groupname_col = "시도명") |> 
  gt_theme_hangul()
당선인 link
서울특별시
이낙연 website
홍익표 website
박성준 website
권영세 website
전혜숙 website
고민정 website
안규백 website
장경태 website
서영교 website
박홍근 website
김영배 website
기동민 website
천준호 website
박용진 website
인재근 website
오기형 website
고용진 website
우원식 website
김성환 website
박주민 website
강병원 website
우상호 website
김영호 website
노웅래 website
정청래 website
황희 website
이용선 website
강선우 website
진성준 website
한정애 website
이인영 website
윤건영 website
최기상 website
김영주 website
김민석 website
김병기 website
이수진 website
유기홍 website
정태호 website
윤희숙 website
박성중 website
태구민 website
박진 website
유경준 website
김웅 website
배현진 website
남인순 website
진선미 website
이해식 website
부산광역시
황보승희 website
안병길 website
서병수 website
이헌승 website
김희곤 website
박수영 website
박재호 website
전재수 website
김도읍 website
하태경 website
김미애 website
최인호 website
조경태 website
백종헌 website
이주환 website
전봉민 website
장제원 website
정동만 website
대구광역시
곽상도 website
류성걸 website
강대식 website
김상훈 website
양금희 website
김승수 website
주호영 website
홍준표 website
홍석준 website
윤재옥 website
김용판 website
추경호 website
인천광역시
배준영 website
허종식 website
윤상현 website
박찬대 website
정일영 website
맹성규 website
윤관석 website
이성만 website
홍영표 website
유동수 website
송영길 website
김교흥 website
신동근 website
광주광역시
윤영덕 website
이병훈 website
송갑석 website
양향자 website
조오섭 website
이형석 website
이용빈 website
민형배 website
대전광역시
장철민 website
황운하 website
박병석 website
박범계 website
조승래 website
이상민 website
박영순 website
울산광역시
박성민 website
이채익 website
김기현 website
권명호 website
이상헌 website
서범수 website
세종특별자치시
홍성국 website
강준현 website
경기도
김승원 website
백혜련 website
김영진 website
박광온 website
김진표 website
김태년 website
윤영찬 website
김은혜 website
김병욱 website
오영환 website
김민철 website
강득구 website
민병덕 website
이재정 website
김경협 website
설훈 website
김상희 website
서영석 website
임오경 website
양기대 website
홍기원 website
유의동 website
김성원 website
전해철 website
김철민 website
고영인 website
김남국 website
심상정 website
한준호 website
홍정민 website
이용우 website
이소영 website
윤호중 website
조응천 website
김한정 website
김용민 website
안민석 website
문정복 website
조정식 website
이학영 website
최종윤 website
정찬민 website
김민기 website
정춘숙 website
이탄희 website
윤후덕 website
박정 website
송석준 website
이규민 website
김주영 website
박상혁 website
송옥주 website
이원욱 website
권칠승 website
소병훈 website
임종성 website
정성호 website
최춘식 website
김선교 website
강원도
허영 website
한기호 website
이광재 website
송기헌 website
권성동 website
이철규 website
이양수 website
유상범 website
충청북도
정정순 website
이장섭 website
도종환 website
변재일 website
이종배 website
엄태영 website
박덕흠 website
임호선 website
충청남도
문진석 website
박완주 website
이정문 website
정진석 website
김태흠 website
이명수 website
강훈식 website
성일종 website
김종민 website
어기구 website
홍문표 website
전라북도
김윤덕 website
이상직 website
김성주 website
신영대 website
김수흥 website
한병도 website
윤준병 website
이용호 website
이원택 website
안호영 website
전라남도
김원이 website
주철현 website
김회재 website
소병철 website
서동용 website
신정훈 website
이개호 website
김승남 website
윤재갑 website
서삼석 website
경상북도
김정재 website
김병욱 website
김석기 website
송언석 website
김형동 website
구자근 website
김영식 website
박형수 website
이만희 website
임이자 website
윤두현 website
김희국 website
정희용 website
경상남도
박완수 website
강기윤 website
최형두 website
윤한홍 website
이달곤 website
박대출 website
강민국 website
정점식 website
하영제 website
민홍철 website
김정호 website
조해진 website
서일준 website
윤영석 website
김두관 website
김태호 website
제주특별자치도
송재호 website
오영훈 website
위성곤 website

1.4 저장하기

코드
## 제21대 국회의원 당선인 url
mp_url_tbl |> 
  write_rds("data/mp21_url_tbl.rds")

2 후보자 경력

코드
mp_url_tbl <- 
  read_rds("data/mp21_url_tbl.rds")

get_career_from_html <- function(url = "https://ko.wikipedia.org/wiki/고민정") {
  
  cat("\n", URLdecode(url), "\n")
  
  webpage <- read_html(url)

  career_vec <- webpage %>% 
    html_nodes(xpath = "//h2[span[@id='주요_경력'] or span[@id='경력']]/following-sibling::ul[1] | //h3[span[@id='경력']]/following-sibling::ul[1]") %>% 
    html_text() 

  if (length(career_vec) > 0) {
    return(career_vec)
  } else {
    # "infobox" 클래스를 가진 table을 찾아 데이터 프레임으로 변환한다
    infobox_table <- webpage %>% 
      html_nodes(".infobox") %>% 
      html_table() %>% 
      .[[1]] |> 
      set_names(c("key", "value"))
    
    # 데이터 프레임에서 "경력" 행을 찾는다
    career_vec <- infobox_table |> 
      filter(key == "경력") |> 
      pull(value)
    
    return(career_vec)
  }  
}

mp_url_career <- mp_url_tbl |> 
  mutate(career = map(url, get_career_from_html)) 

mp_url_career |> 
  mutate(경력 = map_chr(career, str_c, collapse = "\n")) |> 
  mutate(길이 = str_length(경력)) |> 
  arrange(길이) |> 
  filter(길이 == 0) |> 
  mutate(
      link = glue::glue("[website]({url})"),
      link = map(link, gt::md)) |> 
  select(시도명, 당선인, link) |>
  gt(groupname_col = "시도명") |> 
  gt_theme_hangul()


mp_url_career |> 
  write_rds("data/mp21_url_career.rds")

3 분석

3.1 검사, 판사 현황

코드
mp_url_career <- 
  read_rds("data/mp21_url_career.rds")

mp21_career_tbl <- mp_url_career |> 
  mutate(경력 = map_chr(career, str_c, collapse = ";")) |> 
  mutate(검사 = str_extract_all(경력, "사법시험|사법연수원|검사|지청장|검사장|판사")) |> 
  unnest(검사) |>
  filter(!is.na(검사)) |> 
  count(당선인, 검사) |> 
  pivot_wider(names_from = 검사, values_from = n, values_fill = 0) |> 
  select(당선인, 사법시험, 사법연수원, 검사, 지청장, everything()) |> 
  mutate(판검사 = case_when(검사 > 0 ~ "검사",
                            판사 > 0 ~ "판사",
                            TRUE ~ "변호사")) |> 
  relocate(판검사, .after = 당선인) |>
  arrange(판검사)

mp21_career_tbl |> 
  gt() |> 
  gt_theme_hangul() |> 
  cols_align("center") |>
  tab_spanner(label = "검찰청", columns = c("사법시험", "사법연수원", "검사", "지청장"))
당선인 판검사 검찰청 판사
사법시험 사법연수원 검사 지청장
곽상도 검사 1 0 5 2 0
권성동 검사 1 1 3 1 0
권영세 검사 1 1 6 0 0
김도읍 검사 1 1 3 0 0
김웅 검사 1 1 10 1 0
김회재 검사 1 1 15 3 0
박형수 검사 1 1 14 0 0
백혜련 검사 0 0 5 0 0
소병철 검사 1 1 11 1 0
송기헌 검사 1 1 3 0 0
유상범 검사 1 1 13 3 0
정점식 검사 1 1 10 3 0
조응천 검사 1 1 9 1 0
주철현 검사 0 1 12 2 0
홍준표 검사 0 0 2 0 0
김미애 변호사 1 1 0 0 0
김형동 변호사 1 1 0 0 0
박주민 변호사 1 1 0 0 0
서동용 변호사 1 0 0 0 0
송영길 변호사 1 0 0 0 0
오기형 변호사 1 0 0 0 0
이상민 변호사 1 1 0 0 0
이소영 변호사 1 1 0 0 0
이재정 변호사 1 0 0 0 0
이정문 변호사 1 1 0 0 0
정성호 변호사 1 1 0 0 0
진선미 변호사 1 1 0 0 0
홍정민 변호사 1 1 0 0 0
김기현 판사 1 1 0 0 2
김승원 판사 1 1 0 0 2
민홍철 판사 0 0 0 0 1
박범계 판사 0 0 0 0 3
이수진 판사 1 1 0 0 4
이탄희 판사 1 1 0 0 5
주호영 판사 1 0 0 0 6
최기상 판사 1 1 0 0 7

3.2 제21대 당선인 + 법조인

코드
precinct_tbl <- total_elected_all |> 
  filter(sgId == "20200415") |> 
  select(result) |> 
  unnest(result) |> 
  select(시도명 = sdName, 선거구명 = sggName, 정당명=jdName, 당선인 = name)


mp21_precinct_career <- precinct_tbl |> 
  filter(선거구명 != "비례대표") |> 
  left_join(mp21_career_tbl, by = "당선인") |> 
  mutate(법조인 = ifelse(is.na(판검사), "비법조인", 판검사)) 

  
grand_pcnt_func <- function(dataframe) {
  prosecutor_rate <- dataframe  |> 
    count(판검사) |> 
    mutate(검사비율 = n / sum(n)) |> 
    filter(판검사 == "검사") |> 
    pull(검사비율)

  return (prosecutor_rate)
}  

mp21_precinct_career_gt <- mp21_precinct_career |> 
  group_by(정당명, 법조인) |> 
  summarise(법조인수 = n()) |> 
  pivot_wider(names_from = 법조인, values_from = 법조인수, values_fill = 0) |> 
  ungroup() |> 
  arrange(desc(비법조인)) |> 
  select(정당명, 비법조인, 변호사, 판사, 검사) |>
  janitor::adorn_totals(c("col"), name = "합계")  |> 
  mutate(검사비율 = 검사 / 합계) |>
  gt(rowname_col = "정당명") |> 
  gt_theme_hangul() |> 
  cols_align("center") |>
  tab_spanner(label = "법조인", columns = c("검사", "판사", "변호사")) |> 
  grand_summary_rows(
    fns =  list(label = "합계", id = "totals", fn = "sum"),
    fmt = ~ fmt_integer(.),
    side = "bottom"
  ) |> 
  fmt_percent(columns = 검사비율, decimals = 1)  |> 
  grand_summary_rows (
    columns = 검사비율,
    fns =   list("합계" = ~grand_pcnt_func(mp21_precinct_career)),
    fmt = ~ fmt_percent(., decimals = 1)
  ) |>
  tab_header(title = "제21대 총선 법조인 당선인 통계") |>
  tab_footnote(
    footnote = "위키백과: 대한민국_제21대_국회의원_선거",
    locations = cells_title(groups = "title")
  ) |> 
  tab_style(
    style = cell_text(color = "red", weight = "bold", size = "large"),
    locations = cells_body(
      columns = c(검사비율, 검사), 
      rows = 정당명 == "미래통합당"
    )) |> 
  tab_style(
    style = cell_text(color = "black", weight = "bold", size = "large"),
    locations = cells_body(
      columns = c(검사), 
      rows = 정당명 == "무소속"
    )) |>   
  tab_style(
    style = cell_text(color = "black", weight = "bold", size = "large"),
        locations = cells_grand_summary(
      columns = c("검사비율")
    )) |>   
  tab_footnote(
    footnote = "대구 수성구을(홍준표), 강원 강릉시(권성동)",
    locations = cells_body(columns = 검사, rows = 정당명 == "무소속")
  )

mp21_precinct_career_gt
제21대 총선 법조인 당선인 통계1
비법조인 법조인 합계 검사비율
검사 판사 변호사
더불어민주당 140 6 6 11 163 3.7%
미래통합당 73 7 2 2 84 8.3%
무소속 3 22 0 0 5 40.0%
정의당 1 0 0 0 1 0.0%
합계 217 15 8 13 253 5.9%
1 위키백과: 대한민국_제21대_국회의원_선거
2 대구 수성구을(홍준표), 강원 강릉시(권성동)
코드

# mp21_precinct_career_gt |> 
#   gtsave("images/mp21_precinct_career_gt.png")
코드
mp21_precinct_career |> 
  filter(판검사 == "검사") |> 
  count(정당명, 당선인, 시도명, 선거구명) |> 
  arrange(정당명, 시도명) |>
  select(-n) |> 
  group_by(정당명) |>
  gt() |> 
  gt_theme_hangul() |> 
  cols_align("center")
당선인 시도명 선거구명
더불어민주당
송기헌 강원도 원주시을
백혜련 경기도 수원시을
조응천 경기도 남양주시갑
김회재 전라남도 여수시을
소병철 전라남도 순천시광양시곡성군구례군갑
주철현 전라남도 여수시갑
무소속
권성동 강원도 강릉시
홍준표 대구광역시 수성구을
미래통합당
유상범 강원도 홍천군횡성군영월군평창군
정점식 경상남도 통영시고성군
박형수 경상북도 영주시영양군봉화군울진군
곽상도 대구광역시 중구남구
김도읍 부산광역시 북구강서구을
권영세 서울특별시 용산구
김웅 서울특별시 송파구갑