행정안전부 시도별 연령별 인구현황 파일에서 인구수 데이터를 가져온다. 제20대 대통령선거에 맞춰 0-19세는 제외하고 유권자만 분석의 초점으로 정의한다.
library(tidyverse)
library(readxl)
read_excel("data/202110_202110_연령별인구현황_월간.xlsx", skip = 3, sheet = "연령별인구현황",
mois_sido_raw <-range = "B4:B22")
read_excel("data/202110_202110_연령별인구현황_월간.xlsx", skip = 3, sheet = "연령별인구현황",
mois_male_raw <-range = "R4:AB22")
read_excel("data/202110_202110_연령별인구현황_월간.xlsx", skip = 3, sheet = "연령별인구현황",
mois_female_raw <-range = "AE4:AO22")
bind_cols(mois_sido_raw, mois_male_raw) %>%
mois_male_tbl <- pivot_longer(cols = -행정기관, names_to = "연령", values_to = "인구수") %>%
mutate(성별 = "남자") %>%
select(행정기관, 성별, 연령, 인구수)
bind_cols(mois_sido_raw, mois_female_raw) %>%
mois_female_tbl <- pivot_longer(cols = -행정기관, names_to = "연령", values_to = "인구수") %>%
mutate(성별 = "여자") %>%
select(행정기관, 성별, 연령, 인구수)
bind_rows(mois_male_tbl, mois_female_tbl)
mois_raw <-
mois_raw %>%
mois_tbl <- mutate(인구수 = parse_number(인구수)) %>%
filter(!str_detect(행정기관, "전국")) %>%
mutate(연령 = factor(연령, levels = c("0~9세", "10~19세", "20~29세", "30~39세", "40~49세",
"50~59세", "60~69세", "70~79세", "80~89세", "90~99세", "100세 이상"))) %>%
mutate(연령대 = case_when(연령 %in% c("0~9세", "10~19세") ~ "00~19",
%in% c("20~29세", "30~39세") ~ "20~30",
연령 %in% c("40~49세", "50~59세") ~ "40~50",
연령 TRUE ~ "60+")) %>%
mutate(행정기관 = factor(행정기관, levels = c("경기도", "서울특별시", "부산광역시", "경상남도", "인천광역시",
"경상북도", "대구광역시", "충청남도", "전라남도", "전라북도",
"충청북도", "강원도", "대전광역시", "광주광역시", "울산광역시",
"제주특별자치도", "세종특별자치시"))) %>%
filter(연령대 != "00~19")
# library(testthat)
#
# test_that("single number", {
# expect_equal(
# object = mois_tbl %>% summarise(sum(인구수)) %>% pull,
# expected = 51662290 # 51,662,290
# )
# })
%>%
mois_tbl write_csv("data/mois_tbl.csv")
library(gt)
library(gtExtras)
mois_tbl %>%
gender_gt <- group_by(성별) %>%
summarise(인구수 = sum(인구수)) %>%
mutate(비율 = 인구수 / sum(인구수)) %>%
mutate(인구수비율 = glue::glue("{scales::comma(인구수)}<br>{scales::percent(round(비율, 2))}")) %>%
select(성별, 인구수, 비율) %>%
arrange(desc(인구수)) %>%
mutate(누적비율 = cumsum(비율)) %>%
gt() %>%
# fmt_markdown(columns = 인구수비율 ) %>%
gt_theme_538() %>%
tab_header(
title = md("**☀ 제20대 대통령 선거 ☀**"),
subtitle = md("*시도별 인구수*")
%>%
) opt_align_table_header(align = "center") %>%
tab_options(
table.width = "600px",
heading.background.color = "#1E61B0", # R logo 파란색
heading.title.font.size = "20px",
column_labels.background.color = "#F7F7F7", # R logo 회색
column_labels.font.weight = "bold",
stub.background.color = "#ffffff",
stub.font.weight = "bold"
%>%
) tab_source_note(
source_note = md("데이터: 행정안전부 시도별 연령별 인구현황, 2021년 10월")
%>%
) cols_align(
align = "center",
columns = c(성별)
%>%
) fmt_number(
columns = 인구수,
decimals = 0
%>%
) fmt_percent(
columns = c(비율, 누적비율),
decimals = 1
)
gender_gt
☀ 제20대 대통령 선거 ☀ | |||
---|---|---|---|
시도별 인구수 | |||
성별 | 인구수 | 비율 | 누적비율 |
여자 | 21,770,334 | 50.5% | 50.5% |
남자 | 21,377,682 | 49.5% | 100.0% |
데이터: 행정안전부 시도별 연령별 인구현황, 2021년 10월 |
mois_tbl %>%
age_gt <- group_by(연령대) %>%
summarise(인구수 = sum(인구수)) %>%
mutate(비율 = 인구수 / sum(인구수)) %>%
mutate(인구수비율 = glue::glue("{scales::comma(인구수)}<br>{scales::percent(round(비율, 2))}")) %>%
select(연령대, 인구수비율) %>%
gt() %>%
fmt_markdown(columns = 인구수비율 ) %>%
gt_theme_538() %>%
tab_header(
title = md("**☀ 제20대 대통령 선거 ☀**"),
subtitle = md("*연령별 인구수*")
%>%
) opt_align_table_header(align = "center") %>%
tab_options(
table.width = "600px",
heading.background.color = "#1E61B0", # R logo 파란색
heading.title.font.size = "20px",
column_labels.background.color = "#F7F7F7", # R logo 회색
column_labels.font.weight = "bold",
stub.background.color = "#ffffff",
stub.font.weight = "bold"
%>%
) tab_source_note(
source_note = md("데이터: 행정안전부 시도별 연령별 인구현황, 2021년 10월")
)
age_gt
☀ 제20대 대통령 선거 ☀ | |
---|---|
연령별 인구수 | |
연령대 | 인구수비율 |
20~30 | 13,431,836 |
40~50 | 16,792,282 |
60+ | 12,923,898 |
데이터: 행정안전부 시도별 연령별 인구현황, 2021년 10월 |
mois_tbl %>%
sido_gt <- group_by(행정기관) %>%
summarise(인구수 = sum(인구수)) %>%
mutate(비율 = 인구수 / sum(인구수)) %>%
mutate(인구수비율 = glue::glue("{scales::comma(인구수)}<br>{scales::percent(round(비율, 2))}")) %>%
select(행정기관, 인구수, 비율) %>%
arrange(desc(인구수)) %>%
mutate(누적비율 = cumsum(비율)) %>%
gt() %>%
# fmt_markdown(columns = 인구수비율 ) %>%
gt_theme_538() %>%
tab_header(
title = md("**☀ 제20대 대통령 선거 ☀**"),
subtitle = md("*시도별 인구수*")
%>%
) opt_align_table_header(align = "center") %>%
tab_options(
table.width = "600px",
heading.background.color = "#1E61B0", # R logo 파란색
heading.title.font.size = "20px",
column_labels.background.color = "#F7F7F7", # R logo 회색
column_labels.font.weight = "bold",
stub.background.color = "#ffffff",
stub.font.weight = "bold"
%>%
) tab_source_note(
source_note = md("데이터: 행정안전부 시도별 연령별 인구현황, 2021년 10월")
%>%
) cols_align(
align = "center",
columns = c(행정기관)
%>%
) fmt_number(
columns = 인구수,
decimals = 0
%>%
) fmt_percent(
columns = c(비율, 누적비율),
decimals = 1
)
sido_gt
☀ 제20대 대통령 선거 ☀ | |||
---|---|---|---|
시도별 인구수 | |||
행정기관 | 인구수 | 비율 | 누적비율 |
경기도 | 11,118,744 | 25.8% | 25.8% |
서울특별시 | 8,182,185 | 19.0% | 44.7% |
부산광역시 | 2,867,948 | 6.6% | 51.4% |
경상남도 | 2,744,722 | 6.4% | 57.7% |
인천광역시 | 2,454,588 | 5.7% | 63.4% |
경상북도 | 2,225,275 | 5.2% | 68.6% |
대구광역시 | 2,001,956 | 4.6% | 73.2% |
충청남도 | 1,753,637 | 4.1% | 77.3% |
전라남도 | 1,545,964 | 3.6% | 80.9% |
전라북도 | 1,497,999 | 3.5% | 84.3% |
충청북도 | 1,332,287 | 3.1% | 87.4% |
강원도 | 1,301,659 | 3.0% | 90.4% |
대전광역시 | 1,202,943 | 2.8% | 93.2% |
광주광역시 | 1,174,850 | 2.7% | 96.0% |
울산광역시 | 919,453 | 2.1% | 98.1% |
제주특별자치도 | 547,711 | 1.3% | 99.4% |
세종특별자치시 | 276,095 | 0.6% | 100.0% |
데이터: 행정안전부 시도별 연령별 인구현황, 2021년 10월 |
mois_tbl %>%
sido_gender_gt <- group_by(행정기관, 성별) %>%
summarise(인구수 = sum(인구수)) %>%
mutate(비율 = 인구수 / sum(인구수)) %>%
mutate(인구수비율 = glue::glue("{scales::comma(인구수)}<br>{scales::percent(round(비율, 2))}")) %>%
select(-인구수, -비율) %>%
pivot_wider(names_from = 성별, values_from = 인구수비율) %>%
ungroup() %>%
gt() %>%
fmt_markdown(columns = c(남자, 여자) ) %>%
gt_theme_espn() %>%
tab_header(
title = md("**☀ 제20대 대통령 선거 ☀**"),
subtitle = md("*시도별 남녀 인구수*")
%>%
) opt_align_table_header(align = "center") %>%
tab_options(
table.width = "600px",
heading.background.color = "#1E61B0", # R logo 파란색
heading.title.font.size = "20px",
column_labels.background.color = "#F7F7F7", # R logo 회색
column_labels.font.weight = "bold",
stub.background.color = "#ffffff",
stub.font.weight = "bold"
%>%
) tab_source_note(
source_note = md("데이터: 행정안전부 시도별 연령별 인구현황, 2021년 10월")
%>%
) cols_align(
align = "center",
columns = c(행정기관)
)
sido_gender_gt
☀ 제20대 대통령 선거 ☀ | ||
---|---|---|
시도별 남녀 인구수 | ||
행정기관 | 남자 | 여자 |
경기도 | 5,573,522 |
5,545,222 |
서울특별시 | 3,938,078 |
4,244,107 |
부산광역시 | 1,391,261 |
1,476,687 |
경상남도 | 1,373,102 |
1,371,620 |
인천광역시 | 1,222,665 |
1,231,923 |
경상북도 | 1,114,591 |
1,110,684 |
대구광역시 | 977,319 |
1,024,637 |
충청남도 | 894,622 |
859,015 |
전라남도 | 774,608 |
771,356 |
전라북도 | 739,826 |
758,173 |
충청북도 | 673,645 |
658,642 |
강원도 | 652,214 |
649,445 |
대전광역시 | 596,109 |
606,834 |
광주광역시 | 575,511 |
599,339 |
울산광역시 | 471,105 |
448,348 |
제주특별자치도 | 272,346 |
275,365 |
세종특별자치시 | 137,158 |
138,937 |
데이터: 행정안전부 시도별 연령별 인구현황, 2021년 10월 |
mois_tbl %>%
sido_age_gt <- group_by(행정기관, 연령대) %>%
summarise(인구수 = sum(인구수)) %>%
mutate(비율 = 인구수 / sum(인구수)) %>%
mutate(인구수비율 = glue::glue("{scales::comma(인구수)}<br>{scales::percent(round(비율, 2))}")) %>%
select(-인구수, -비율) %>%
pivot_wider(names_from = 연령대, values_from = 인구수비율) %>%
ungroup() %>%
gt() %>%
fmt_markdown(columns = c(`20~30`, `40~50`, `60+`) ) %>%
gt_theme_espn() %>%
tab_header(
title = md("**☀ 제20대 대통령 선거 ☀**"),
subtitle = md("*시도별 연령별 인구수*")
%>%
) opt_align_table_header(align = "center") %>%
tab_options(
table.width = "600px",
heading.background.color = "#1E61B0", # R logo 파란색
heading.title.font.size = "20px",
column_labels.background.color = "#F7F7F7", # R logo 회색
column_labels.font.weight = "bold",
stub.background.color = "#ffffff",
stub.font.weight = "bold"
%>%
) tab_source_note(
source_note = md("데이터: 행정안전부 시도별 연령별 인구현황, 2021년 10월")
%>%
) cols_align(
align = "center",
columns = c(행정기관)
)
sido_age_gt
☀ 제20대 대통령 선거 ☀ | |||
---|---|---|---|
시도별 연령별 인구수 | |||
행정기관 | 20~30 | 40~50 | 60+ |
경기도 | 3,704,923 |
4,558,558 |
2,855,263 |
서울특별시 | 2,873,770 |
2,993,544 |
2,314,871 |
부산광역시 | 826,544 |
1,058,617 |
982,787 |
경상남도 | 749,248 |
1,106,448 |
889,026 |
인천광역시 | 794,083 |
990,423 |
670,082 |
경상북도 | 558,636 |
831,492 |
835,147 |
대구광역시 | 598,427 |
793,145 |
610,384 |
충청남도 | 499,506 |
664,931 |
589,200 |
전라남도 | 373,979 |
564,851 |
607,134 |
전라북도 | 391,042 |
559,053 |
547,904 |
충청북도 | 386,590 |
507,474 |
438,223 |
강원도 | 338,742 |
483,875 |
479,042 |
대전광역시 | 400,640 |
471,593 |
330,710 |
광주광역시 | 389,570 |
471,375 |
313,905 |
울산광역시 | 284,257 |
390,936 |
244,260 |
제주특별자치도 | 162,441 |
225,970 |
159,300 |
세종특별자치시 | 99,438 |
119,997 |
56,660 |
데이터: 행정안전부 시도별 연령별 인구현황, 2021년 10월 |
# sido_age_gt %>%
# gtsave(filename = "sido_age_gt.png", path = "fig")
::loadfonts()
extrafont
%>%
mois_tbl group_by(행정기관) %>%
summarise(인구수 = sum(인구수)) %>%
ungroup() %>%
ggplot(aes(x = fct_reorder(행정기관, 인구수), y = 인구수)) +
geom_col(width =0.1, color = "#2E7DBF") +
geom_point(size = 3, color = "#0F1F48") +
coord_flip() +
scale_y_continuous(labels = scales::comma, limits = c(0, 15000000)) +
labs(x = "", y = "",
title = "제20대 대통령 선거",
subtitle = "시도별 유권자") +
theme_light(base_family = "NanumBarunpen")
%>%
mois_tbl group_by(행정기관, 연령대) %>%
summarise(인구수 = sum(인구수)) %>%
ungroup() %>%
mutate(연령대 = factor(연령대, levels = c("20~30", "40~50", "60+")) %>% fct_rev) %>%
ggplot(aes(x = fct_reorder(행정기관, 인구수), y = 인구수, fill = 연령대)) +
geom_col(width =0.3, position = "fill") +
coord_flip() +
scale_y_continuous(labels = scales::percent) +
labs(x = "", y = "",
title = "제20대 대통령 선거",
subtitle = "시도별 유권자") +
theme_light(base_family = "NanumBarunpen") +
theme(legend.position = "top") +
guides(fill = guide_legend(reverse = TRUE))
데이터 과학자 이광춘 저작
kwangchun.lee.7@gmail.com