국회의원 당선인

국회의원 당선인 명부

저자
소속

1 데이터셋

1.0.1 국회의원 당선인

코드
library(tidyverse)
library(rvest)

roll_url <- glue::glue("http://info.nec.go.kr/electioninfo/electionInfo_report.xhtml?",
                       "electionId=0000000000",
                       "&requestURI=%2Felectioninfo%2F0000000000%2Fep%2Fepei01.jsp&topMenuId=EP", 
                       "&secondMenuId=EPEI01",
                       "&menuId=EPEI01",
                       "&statementId=EPEI01_%231",
                       "&oldElectionType=1",
                       "&electionType=2",
                       "&electionName=20200415", 
                       "&electionCode=2",
                       "&cityCode=1100",
                       "&proportionalRepresentationCode=-1",
                       "&townCode=-1",
                       "&x=57",
                       "&y=21")

roll_raw <- read_html(roll_url) |> 
  html_table(header = TRUE) %>%
  .[[1]]

roll_tbl <- roll_raw |> 
  janitor::clean_names(ascii = FALSE) |>
  mutate(나이 = str_extract(생년월일_연령, "\\((\\d+)세\\)") |> parse_number()) |> 
  separate(득표수_득표율, into = c("득표수", "득표율"), sep = "\\(") |>
  separate(성명_한자, into = c("성명", "한자명"), sep = "\\(") |> 
  mutate(across(득표수:득표율, parse_number)) |> 
  select(선거구명, 정당명, 성명, 성별, 나이, 득표수, 득표율)

roll_tbl

1.1 함수

코드
get_electors <- function(sido_cd = "1100") {
  
  roll_url <- glue::glue("http://info.nec.go.kr/electioninfo/electionInfo_report.xhtml?",
                       "electionId=0000000000",
                       "&requestURI=%2Felectioninfo%2F0000000000%2Fep%2Fepei01.jsp&topMenuId=EP", 
                       "&secondMenuId=EPEI01",
                       "&menuId=EPEI01",
                       "&statementId=EPEI01_%231",
                       "&oldElectionType=1",
                       "&electionType=2",
                       "&electionName=20200415", 
                       "&electionCode=2",
                       "&cityCode={sido_cd}",
                       "&proportionalRepresentationCode=-1",
                       "&townCode=-1",
                       "&x=57",
                       "&y=21")
  
  roll_raw <- read_html(roll_url) |> 
    html_table(header = TRUE) %>%
    .[[1]]
  
  roll_tbl <- roll_raw |> 
    janitor::clean_names(ascii = FALSE) |>
    mutate(나이 = str_extract(생년월일_연령, "\\((\\d+)세\\)") |> parse_number()) |> 
    separate(득표수_득표율, into = c("득표수", "득표율"), sep = "\\(") |>
    separate(성명_한자, into = c("성명", "한자명"), sep = "\\(") |> 
    mutate(across(득표수:득표율, parse_number)) |> 
    select(선거구명, 정당명, 성명, 성별, 나이, 득표수, 득표율)
  
  roll_tbl
}

## 부산광역시
get_electors("2600")

1.2 시도별 당선자

코드

sido_cd <- tribble(~"시도코드", ~"시도명",
                    "1100", "서울특별시", 
                    "2600", "부산광역시",
                    "2700", "대구광역시", 
                    "2800", "인천광역시",
                    "2900", "광주광역시", 
                    "3000", "대전광역시",
                    "3100", "울산광역시", 
                    "5100", "세종특별자치시",
                    "4100", "경기도", 
                    "4200", "강원도",
                    "4300", "충청북도", 
                    "4400", "충청남도",
                    "4500", "전라북도", 
                    "4600", "전라남도",
                    "4700", "경상북도", 
                    "4800", "경상남도",
                    "4900", "제주특별자치도") 

electors_raw <- sido_cd |> 
  mutate(data = map(시도코드, get_electors))
코드
electors_raw |> 
  write_rds("data/제21대_국회의원_당선자.rds")

2 제21대 국회의원 당선자 분석

코드
electors_raw <- 
  read_rds("data/제21대_국회의원_당선자.rds")

electors_tbl <- electors_raw |>
  unnest(data) |> 
  mutate(정당명 = case_when(str_detect(정당명, "더불어민주당") ~ "민주당",
                          str_detect(정당명, "미래통합당")   ~ "국민의힘",
                          TRUE ~ 정당명))

electors_tbl |> 
  ggplot(aes(x = 나이, y = 득표율, color = 정당명)) +
    geom_point() +
    facet_wrap(~시도명) +
    theme_korean() +
    scale_color_manual(values = party_name_palette)
코드
electors_age <- bind_rows(
  electors_tbl |> 
    slice_min( order_by = 나이, n = 10),
  electors_tbl |> 
    slice_max( order_by = 나이, n = 10)
)

electors_age |> 
  ggplot(aes(x = 득표수, y = 득표율, color = 정당명)) +
    geom_point()

electors_tbl |> 
  group_by(정당명) |> 
  summarise(의원수 = n(),
            최소_연령 = min(나이),
            평균_연령 = mean(나이),
            중위_연령 = median(나이),
            최고_연령 = max(나이))

electors_tbl |> 
  filter(정당명 %in% c("민주당", "국민의힘")) |> 
  ggplot(aes(x=정당명, y = 나이, color = 정당명)) +
    geom_boxplot() +
    geom_jitter() +
    theme_korean() +
    scale_fill_manual(values = party_name_palette) +
    scale_color_manual(values = party_name_palette) +
    facet_wrap(~시도명)

3 데이터

3.1 제19대 국회의원

코드
get_electors_by_election <- function(election_id = "20120411", sido_cd = "1100") {
  
  roll_url <- glue::glue("http://info.nec.go.kr/electioninfo/electionInfo_report.xhtml?",
                       "electionId=0000000000",
                       "&requestURI=%2Felectioninfo%2F0000000000%2Fep%2Fepei01.jsp&topMenuId=EP", 
                       "&secondMenuId=EPEI01",
                       "&menuId=EPEI01",
                       "&statementId=EPEI01_%231",
                       "&oldElectionType=1",
                       "&electionType=2",
                       "&electionName={election_id}", 
                       "&electionCode=2",
                       "&cityCode={sido_cd}",
                       "&proportionalRepresentationCode=-1",
                       "&townCode=-1",
                       "&x=57",
                       "&y=21")
  
  roll_raw <- read_html(roll_url) |> 
    html_table(header = TRUE) %>%
    .[[1]]
  
  roll_tbl <- roll_raw |> 
    janitor::clean_names(ascii = FALSE) |>
    mutate(나이 = str_extract(생년월일_연령, "\\((\\d+)세\\)") |> parse_number()) |> 
    separate(득표수_득표율, into = c("득표수", "득표율"), sep = "\\(") |>
    separate(성명_한자, into = c("성명", "한자명"), sep = "\\(") |> 
    mutate(across(득표수:득표율, parse_number)) |> 
    select(선거구명, 정당명, 성명, 성별, 나이, 득표수, 득표율)
  
  roll_tbl
}

## 제20대, 부산광역시
get_electors_by_election("20160413", "2600")

3.2 전체 선거, 당선자

코드
election_cd <- tribble(~"선거코드", ~"선거",
                       "20200415", "제21대",
                       "20160413", "제20대",
                       "20120411", "제19대",
                       "20080409", "제18대",
                       "20040415", "제17대",
                       "20000413", "제16대",
                       "19960411", "제15대",
                       "19920324", "제14대",
                       "19880426", "제13대",
                       "19850212", "제12대",
                       "19810325", "제11대",
                       "19781212", "제10대",
                       "19730227", "제9대",
                       "19710525", "제8대",
                       "19670608", "제7대",
                       "19631126", "제6대",
                       "19600729", "제5대",
                       "19580502", "제4대",
                       "19540520", "제3대",
                       "19500530", "제2대",
                       "19480510", "제1대")

election_tbl <- election_cd |> 
  mutate(시도 = list(sido_cd)) |> 
  unnest(시도) |> 
  filter(선거 %in% c("제19대", "제20대", "제21대")) |> 
  mutate(data = map2(선거코드, 시도코드, get_electors_by_election))
코드
election_tbl |> 
  write_rds("data/국회의원_19_21_당선자.rds")

4 분석

코드
election_tbl <- 
  read_rds("data/국회의원_19_21_당선자.rds")

election_tbl |> 
  unnest(data) |> 
  ggplot(aes(x = 나이, y = 득표율, color = 선거)) +
    geom_point() +
    geom_smooth(method = "lm", se = FALSE) +
    facet_wrap(~시도명)
코드
election_tbl |> 
  unnest(data)  |> 
  slice_min(order_by = 나이, n = 50) |> 
  count(정당명)