비율 계산

데이터 준비

이번 글에서는 2023년 시군구별 주민등록인구 데이터를 활용해서 각 시도에서 시, 군, 구가 차지하는 인구 비중을 계산하는 방법을 알아보겠습니다. 또한, 데이터를 정리해서 보고서에 바로 활용할 수 있는 표 형태로 변환하는 과정도 다룰 예정입니다.

분석에 사용할 데이터는 통계청의 시군구별 주민등록인구 데이터입니다. 이 데이터는 시도, 시군구, 주민등록인구수로 구성되어 있습니다. 데이터를 불러오고 나서 간단히 확인한 후, 정리 작업을 진행하겠습니다.

# 패키지 로드
library(tidyverse)
library(readxl)

# 데이터 로드
data <- read_xlsx("데이터/주민등록인구_시도_시군구_2023.xlsx", skip=1)

# 데이터 확인
head(data)
## # A tibble: 6 × 3
##   `행정구역별(1)` `행정구역별(2)` `계 (명)`
##   <chr>           <chr>               <dbl>
## 1 전국            소계             51325329
## 2 서울특별시      소계              9386034
## 3 서울특별시      종로구             139417
## 4 서울특별시      중구               121312
## 5 서울특별시      용산구             213151
## 6 서울특별시      성동구             277361

열 이름을 알기 쉽게 바꾸고, 전국 데이터를 제외하며, 불필요한 ‘소계’ 데이터를 제거합니다. 마지막으로, 각 시군구가 시, 군, 구 중 어디에 해당하는지 구분을 추가합니다.

data2 <- data %>% 
  rename(시도 = `행정구역별(1)`,
         시군구 = `행정구역별(2)`,
         주민등록인구수 = `계 (명)`) %>% 
  filter(시도 != "전국",
         (시도 == "세종특별자치시")|(시군구 != "소계")) %>% 
  mutate(시군구 = case_when(시도 == "세종특별자치시" ~ "세종특별자치시",
                         T ~ 시군구),
         구분 = case_when(grepl("시$", 시군구) ~ "시",
                        grepl("군$", 시군구) ~ "군",
                        grepl("구$", 시군구) ~ "구"))

head(data2)
## # A tibble: 6 × 4
##   시도       시군구   주민등록인구수 구분 
##   <chr>      <chr>             <dbl> <chr>
## 1 서울특별시 종로구           139417 구   
## 2 서울특별시 중구             121312 구   
## 3 서울특별시 용산구           213151 구   
## 4 서울특별시 성동구           277361 구   
## 5 서울특별시 광진구           335554 구   
## 6 서울특별시 동대문구         341149 구

시도별 주민등록인구 비율 계산하기

각 시도에서 시, 군, 구가 차지하는 인구 비중을 계산해보겠습니다. 이 작업을 통해 각 시도에서 어떤 지역 유형(시, 군, 구)이 인구의 대부분을 차지하고 있는지 쉽게 파악할 수 있습니다. 먼저, 시도와 구분별로 인구수를 합산하고, 시도별 전체 인구에서 각 시, 군, 구가 차지하는 비율을 계산합니다.

sum <- data2 %>% 
  group_by(시도, 구분) %>% 
  summarise(주민등록인구수 = sum(주민등록인구수, na.rm = TRUE)) %>% 
  group_by(시도) %>% 
  mutate(비율 = 주민등록인구수 / sum(주민등록인구수, na.rm = TRUE))

head(sum)
## # A tibble: 6 × 4
## # Groups:   시도 [3]
##   시도           구분  주민등록인구수   비율
##   <chr>          <chr>          <dbl>  <dbl>
## 1 강원특별자치도 군            398407 0.261 
## 2 강원특별자치도 시           1129400 0.739 
## 3 경기도         군            229124 0.0168
## 4 경기도         시          13401697 0.983 
## 5 경상남도       군            446562 0.137 
## 6 경상남도       시           2804596 0.863

보고용 표 만들기

분석 결과를 정리해서 보고서에 활용할 수 있는 표를 만들어보겠습니다. 보고용 표를 만드는 방법은 데이터를 표현하는 목적과 가독성에 따라 달라질 수 있습니다. 이번에는 세 가지 방식으로 데이터를 정리하는 방법을 제안합니다.

  1. 수와 비율을 세로로 정렬하고 합계 추가하기: 인구 수와 비율을 세로로 나열해 데이터를 직관적으로 보여줍니다
  2. 수와 비율을 가로로 정렬하고 합계 추가하기: 데이터를 가로로 배열해 열 공간을 효율적으로 사용합니다
  3. 하나의 셀에 수와 비율을 병기하고 합계 추가하기: 하나의 셀에 수치와 비율을 함께 표시해 요약 정보를 간결하게 제공합니다

수와 비율을 세로로 정렬하고 합계 추가하기

주민등록인구 수와 비율을 세로로 배열하고, 마지막에 합계를 추가해 보고용 표를 만듭니다.

  • 변수 이름 변경: rename
  • 숫자 포맷팅: comma, percent
  • 시군구 정렬: mutate, factor
  • 데이터 변환: pivot_longer, pivot_wider
  • 세부 데이터와 합계 데이터 통합: left_join
library(scales)

rpt1_sebu <- sum %>% 
  rename(`인구 수(명)` = 주민등록인구수,
         `비율(%)` = 비율) %>% 
  mutate(구분 = factor(구분, levels = c("시", "군", "구")),
         `인구 수(명)` = comma(`인구 수(명)`),
         `비율(%)` = percent(`비율(%)`, suffix = "", accuracy = .1)) %>% 
  pivot_longer(cols = `인구 수(명)`:`비율(%)`, 
               names_to = "구분2", 
               values_to = "값") %>% 
  pivot_wider(id_cols = c(시도, 구분2), 
              names_from = 구분, 
              values_from = ,
              names_sort = TRUE)

rpt1_sum <- sum %>% 
  group_by(시도) %>% 
  summarise(`인구 수(명)` = sum(주민등록인구수, na.rm = TRUE),
            `비율(%)` = sum(비율, na.rm = TRUE)) %>% 
  mutate(`인구 수(명)` = comma(`인구 수(명)`),
         `비율(%)` = percent(`비율(%)`, suffix = "", accuracy = .1)) %>% 
  pivot_longer(cols=-시도, 
               names_to = "구분2", 
               values_to = "합계")

rpt1 <- rpt1_sebu %>% 
  left_join(rpt1_sum, by=c("시도", "구분2")) %>% 
  rename(구분 = 구분2)

head(rpt1)
## # A tibble: 6 × 6
## # Groups:   시도 [3]
##   시도           구분        시         군      구    합계      
##   <chr>          <chr>       <chr>      <chr>   <chr> <chr>     
## 1 강원특별자치도 인구 수(명) 1,129,400  398,407 <NA>  1,527,807 
## 2 강원특별자치도 비율(%)     73.9       26.1    <NA>  100.0     
## 3 경기도         인구 수(명) 13,401,697 229,124 <NA>  13,630,821
## 4 경기도         비율(%)     98.3       1.7     <NA>  100.0     
## 5 경상남도       인구 수(명) 2,804,596  446,562 <NA>  3,251,158 
## 6 경상남도       비율(%)     86.3       13.7    <NA>  100.0

수와 비율을 가로로 정렬하고 합계 추가하기

주민등록인구 수와 비율을 가로로 배열하고, 마지막에 합계를 추가해 보고용 표를 만듭니다.

  • 변수 이름 변경: rename
  • 숫자 포맷팅: comma, percent
  • 시군구 및 합계 정렬: mutate, factor
  • 데이터 변환: pivot_longer, pivot_wider
  • 세부 데이터와 합계 데이터 통합: bind_rows
rpt2_sebu <- sum %>% 
  rename(`인구 수(명)` = 주민등록인구수,
         `비율(%)` = 비율)

rpt2_sum <- sum %>% 
  group_by(시도) %>% 
  summarise(`인구 수(명)` = sum(주민등록인구수, na.rm = TRUE),
            `비율(%)` = sum(비율, na.rm = TRUE)) %>% 
  mutate(구분 = "합계")

rpt2 <- rpt2_sebu %>% 
  bind_rows(rpt2_sum) %>% 
  mutate(구분 = factor(구분, levels = c("시", "군", "구", "합계")),
         `인구 수(명)` = comma(`인구 수(명)`),
         `비율(%)` = percent(`비율(%)`, suffix = "", accuracy = .1)) %>% 
  pivot_wider(id_cols = 시도, 
              names_from = 구분, 
              values_from = `인구 수(명)`:`비율(%)`,
              names_glue = "{구분}_{.value}",
              names_vary = "slowest",
              names_sort = TRUE)

head(rpt2)
## # A tibble: 6 × 9
## # Groups:   시도 [6]
##   시도           `시_인구 수(명)` `시_비율(%)` `군_인구 수(명)` `군_비율(%)`
##   <chr>          <chr>            <chr>        <chr>            <chr>       
## 1 강원특별자치도 1,129,400        73.9         398,407          26.1        
## 2 경기도         13,401,697       98.3         229,124          1.7         
## 3 경상남도       2,804,596        86.3         446,562          13.7        
## 4 경상북도       2,065,707        80.9         488,617          19.1        
## 5 광주광역시     <NA>             <NA>         <NA>             <NA>        
## 6 대구광역시     <NA>             <NA>         285,072          12.0        
## # ℹ 4 more variables: `구_인구 수(명)` <chr>, `구_비율(%)` <chr>,
## #   `합계_인구 수(명)` <chr>, `합계_비율(%)` <chr>

하나의 셀에 수와 비율을 병기하고 합계 추가하기

주민등록인구 수와 비율을 하나의 셀에 병기하고, 마지막에 합계를 추가해 보고용 표를 만듭니다.

  • 변수 이름 변경: rename
  • 숫자 포맷팅: comma, percent
  • 수 및 비율 병기: mutate, paste0
  • 시군구 및 합계 정렬: mutate, factor
  • 데이터 변환: pivot_wider
  • 세부 데이터와 합계 데이터 통합: bind_rows
rpt3_sebu <- sum %>% 
  rename(`인구 수(명)` = 주민등록인구수,
         `비율(%)` = 비율) %>% 
  mutate(`인구 수(명)` = comma(`인구 수(명)`),
         `비율(%)` = percent(`비율(%)`, suffix = "", accuracy = .1)) %>% 
  mutate(`인구 수(비율)` = paste0(`인구 수(명)`,
                             "\n(",
                             `비율(%)`,
                             ")"))

rpt3_sum <- sum %>% 
  group_by(시도) %>% 
  summarise(`인구 수(명)` = sum(주민등록인구수, na.rm = TRUE),
            `비율(%)` = sum(비율, na.rm = TRUE)) %>% 
  mutate(`인구 수(명)` = comma(`인구 수(명)`),
         `비율(%)` = percent(`비율(%)`, suffix = "", accuracy = .1),
         `인구 수(비율)` = paste0(`인구 수(명)`,
                             "\n(",
                             `비율(%)`,
                             ")"),
         구분 = "합계")

rpt3 <- rpt3_sebu %>% 
  bind_rows(rpt3_sum) %>% 
  mutate(구분 = factor(구분, levels = c("시", "군", "구", "합계"))) %>% 
  pivot_wider(id_cols = 시도, 
              names_from = 구분, 
              values_from = `인구 수(비율)`,
              names_sort = TRUE)

head(rpt3)
## # A tibble: 6 × 5
## # Groups:   시도 [6]
##   시도           시                   군                구                 합계 
##   <chr>          <chr>                <chr>             <chr>              <chr>
## 1 강원특별자치도 "1,129,400\n(73.9)"  "398,407\n(26.1)"  <NA>              "1,5…
## 2 경기도         "13,401,697\n(98.3)" "229,124\n(1.7)"   <NA>              "13,…
## 3 경상남도       "2,804,596\n(86.3)"  "446,562\n(13.7)"  <NA>              "3,2…
## 4 경상북도       "2,065,707\n(80.9)"  "488,617\n(19.1)"  <NA>              "2,5…
## 5 광주광역시      <NA>                 <NA>             "1,419,237\n(100.… "1,4…
## 6 대구광역시      <NA>                "285,072\n(12.0)" "2,089,888\n(88.0… "2,3…

이번 시간에는 2023년 시군구별 주민등록인구 데이터를 활용해서 시도별 인구 비중을 계산하고, 다양한 형식으로 보고용 표를 만들어보았습니다. 이 과정을 통해 데이터를 더 직관적으로 정리하고 분석결과를 효과적으로 전달할 수 있는 방법을 배웠기를 바랍니다. 다른 데이터셋에도 한 번 응용해보세요!