본문 바로가기
  • plotly로 바로쓰는 동적시각화 in R & 파이썬
데이터 전처리

연도별 시도별 비정규 교원 1인당 학생수 in R - rank()

by 아참형인간 2022. 7. 13.
rank.knit

rank()를 사용한 순위 구하기

데이터 분석에서 자신이 원하는 데이터를 산출하고 나면 대부분 수행하는 것이 어떤 데이터가 가장 좋고 어떤 데이터가 가장 나쁜지를 확인하게 된다. 이 경우 가장 쉽게 사용되는 방법이 원하는 데이터로 정렬하는 방법이다. 하지만 경우에 따라 순위를 명기해야 할 때가 있다. 전체를 대상으로 순위를 산출한다면 전체 데이터를 정렬하고 처음부터 마지막까지 순번을 붙여주면 되지만 그룹화된 데이터에 대한 그룹별 순위를 산출해야 한다면 이 방법은 사용할 수 없다. 이런 경우 사용할 수 있는 함수가 rank()이다.

rank()의 사용법을 알아보기 위해 전국 17개 시도의 비정규 교원 1인당 학생수 데이터를 만들어 보겠다.

데이터 import

17개 시도의 비정규 교원 1인당 학생수를 산출하기 위해 교육통계 서비스 홈페이지의 한국교육개발원 교육통계 서비스 홈페이지의 ‘주제별 공개 데이터’ 메뉴 중 ’[04] 행정구역별 교육통계 요약_학교수 학생수 입학 졸업 교원 직원 학업중단 다문화 등(1999-2021)’의 https://kess.kedi.re.kr/post/6731852?itemCode=04&menuId=m_02_04_03_01 ’유초 주요-04 시도별 행정구역별 교육통계 현황_방통제외(1999-2021)_20220523y.xlsx’을 사용하였다.

이 엑셀파일에는 1999년부터 2021년까지의 시도별 학제별 각종 데이터가 들어있는데 연도마다 포맷이 다소 다르기 때문에 sheet에 따라 연도별 데이터가 저장되어 있다. 이 중 2015~2021년까지의 데이터를 다음과 같이 가져오겠다.

df_provinfo_21 <- read_excel('D:/R/data/유초 주요-03 시도별 교육통계 현황_방통포함(1999-2021)_20220523y.xlsx', 
                               sheet = '2021', skip = 11,
                               col_types = c(rep('text', 3), rep('numeric', 170)), 
                               col_names = FALSE)

df_provinfo_1520 <- read_excel('D:/R/data/유초 주요-03 시도별 교육통계 현황_방통포함(1999-2021)_20220523y.xlsx', 
                               sheet = '2015-2020', skip = 12,
                               col_types = c(rep('text', 3), rep('numeric', 138)), 
                               col_names = FALSE)

데이터 전처리

가져온 데이터 중에 필요한 데이터만 가져오겠다. 여기서 필요한 데이터는 연도, 시도, 학제, 학급수, 학생수, 전체 교원수, 비정규 교원수이다. 이 중 비정규 교원수는 엑셀 파일에 들어있지 않은 데이터이기 때문에 기간제 교원수와 시간강사수를 합쳐서 만들어 내야한다. 또 여러 학제 중 초등학교, 중학교, 고등학교 데이터만 사용하기 위해 다음과 같이 전처리한다.

## 21년 데이터 전처리
df_provinfo_21 <- df_provinfo_21 |> select(1, 2, 3, 15, 25, 73, 112, 115)

colnames(df_provinfo_21) <- c('연도', '시도', '학제', '학급수', '학생수', '전체교원수', '기간제교원수', '시간강사수')

df_provinfo_21 <- df_provinfo_21 |> 
  mutate(비정규교원당학생수 = 학생수 / (기간제교원수 + 시간강사수))

df_비정규교원당학생수_21 <- df_provinfo_21 |> 
  filter(학제 %in% c('초등학교', '중학교', '고등학교'))

## 15~20년 데이터 전처리
df_provinfo_1520 <- df_provinfo_1520 |> select(1, 2, 3, 5, 20, 41, 80, 83)

colnames(df_provinfo_1520) <- c('연도', '시도', '학제', '학급수', '학생수', '전체교원수', '기간제교원수', '시간강사수')

df_provinfo_1520 <- df_provinfo_1520 |> 
  mutate(비정규교원당학생수 = 학생수 / (기간제교원수 + 시간강사수))

df_비정규교원당학생수_1520 <- df_provinfo_1520 |> 
  filter(학제 %in% c('초등학교', '중학교', '고등학교')) |> arrange(연도)

이제 두 데이터를 붙이면 15~21년까지의 데이터가 완성된다.

df_비정규교원당학생수 <- rbind(df_비정규교원당학생수_1520, df_비정규교원당학생수_21)

df_비정규교원당학생수 |> head(10)
## # A tibble: 10 x 9
##    연도  시도  학제     학급수  학생수 전체교원수 기간제교원수 시간강사수
##    <chr> <chr> <chr>     <dbl>   <dbl>      <dbl>        <dbl>      <dbl>
##  1 2015  전국  초등학교 120063 2714610     182658         6451       2671
##  2 2015  전국  중학교    54855 1585951     111247        16065       4279
##  3 2015  전국  고등학교  59668 1788266     134999        19526       2569
##  4 2015  서울  초등학교  18780  450675      29627          696        440
##  5 2015  서울  중학교     9249  263466      18076         2642       1633
##  6 2015  서울  고등학교  10233  308306      22870         3619        648
##  7 2015  부산  초등학교   7063  154283      10414          201         97
##  8 2015  부산  중학교     3394   95020       6673         1049        370
##  9 2015  부산  고등학교   3934  109773       8719         1546        118
## 10 2015  대구  초등학교   5821  129583       8869          103        141
## # ... with 1 more variable: 비정규교원당학생수 <dbl>

rank()를 사용한 순위 산출

이제 앞서 전처리한 데이터에 대해 rank()를 사용하여 순위를 산출하면 다음과 같다.

df_비정규교원당학생수_rank <- df_비정규교원당학생수 |> mutate(rank = rank(비정규교원당학생수))

df_비정규교원당학생수_rank |> arrange(rank)
## # A tibble: 378 x 10
##    연도  시도  학제     학급수 학생수 전체교원수 기간제교원수 시간강사수
##    <chr> <chr> <chr>     <dbl>  <dbl>      <dbl>        <dbl>      <dbl>
##  1 2021  부산  고등학교   3453  73499       7817         2034        102
##  2 2021  경북  고등학교   3116  64967       7200         1541        206
##  3 2020  부산  고등학교   3464  76573       7933         1903         75
##  4 2021  서울  고등학교   9194 216319      21039         4839        613
##  5 2020  경북  고등학교   3182  66899       7212         1470        152
##  6 2021  전남  고등학교   2321  46781       5715         1073         54
##  7 2021  대구  고등학교   2754  63074       6500         1436         66
##  8 2019  부산  고등학교   3554  82132       8099         1845         91
##  9 2021  광주  고등학교   1771  43694       4025          997         16
## 10 2021  부산  중학교     3016  75357       6176         1500        236
## # ... with 368 more rows, and 2 more variables: 비정규교원당학생수 <dbl>,
## #   rank <dbl>

위의 결과를 보면 2021년 부산 고등학교의 비정규 교원 1인당 학생수가 가장 적은 것으로 나타난다. 이와 같이 rank()는 순위의 기준이 되는 열에 대해 오름차순의 순위를 산출하여 넣어준다.

만약 오름차순이 아니라 내림차순으로 순위를 산출하려면 다음과 같이 산출할 수 있다.

df_비정규교원당학생수 |> mutate(rank = rank(-비정규교원당학생수)) |> 
  arrange(rank) |> head(10)
## # A tibble: 10 x 10
##    연도  시도  학제     학급수 학생수 전체교원수 기간제교원수 시간강사수
##    <chr> <chr> <chr>     <dbl>  <dbl>      <dbl>        <dbl>      <dbl>
##  1 2021  광주  초등학교   4030  84998       6022           88         18
##  2 2016  광주  초등학교   3985  89095       6027           86         28
##  3 2017  대구  초등학교   5507 124708       8900           99         62
##  4 2017  광주  초등학교   3996  88189       6025           87         29
##  5 2018  광주  초등학교   4050  88622       6084           93         27
##  6 2020  광주  초등학교   4044  86419       6046           95         24
##  7 2016  대구  초등학교   5555 125541       8873           81         96
##  8 2018  부산  초등학교   6856 152775      10170          190         40
##  9 2017  부산  초등학교   6840 150863      10173          186         42
## 10 2019  광주  초등학교   4071  88990       6068          109         29
## # ... with 2 more variables: 비정규교원당학생수 <dbl>, rank <dbl>

그룹별 rank()를 사용한 순위 산출

위의 두가지 데이터를 전반적으로 보면 비정규 교원 1인당 학생수가 적은 순위는 대부분 2019~2021년의 고등학교 데이터이고 교원 1인당 학생수가 많은 순위는 연도는 여러 연도에 분포되지만 학제가 초등학교에 집중되어 있다. 이는 연도와 학제에 따라 비정규 교원당 학생수의 범위가 차이가 난다는 것을 알 수 있다. 따라서 연도별, 학제별로 순위를 산출하기 위해서는 group_by()rank()를 같이 사용해야 한다.

먼저 학제별 비정규 교원 1인당 학생수의 순위는 다음과 같이 구할 수 있다.

df_비정규교원당학생수_rank <- df_비정규교원당학생수 |> group_by(학제) |>
  mutate(rank = rank(비정규교원당학생수))

df_비정규교원당학생수_rank |> arrange(rank) |>
  head(9)
## # A tibble: 9 x 10
## # Groups:   학제 [3]
##   연도  시도  학제     학급수 학생수 전체교원수 기간제교원수 시간강사수
##   <chr> <chr> <chr>     <dbl>  <dbl>      <dbl>        <dbl>      <dbl>
## 1 2021  부산  중학교     3016  75357       6176         1500        236
## 2 2021  부산  고등학교   3453  73499       7817         2034        102
## 3 2021  경북  초등학교   6428 127912      10586          720         54
## 4 2019  경기  초등학교  31148 769744      46568         4243        364
## 5 2021  경북  중학교     2968  63732       6587         1273        190
## 6 2021  경북  고등학교   3116  64967       7200         1541        206
## 7 2020  부산  고등학교   3464  76573       7933         1903         75
## 8 2020  경북  중학교     2917  62499       6489         1179        157
## 9 2021  경기  초등학교  31670 763912      48013         4293        247
## # ... with 2 more variables: 비정규교원당학생수 <dbl>, rank <dbl>

위의 데이터를 보면 초등학교 순위는 2021년 경북, 2019년 경기, 2021년 경기의 순서이고 중학교는 2021년 부산, 2021 경북, 2020년 경북의 순이며 고등학교는 2021년 부산, 2021년 경북, 2020년 부산의 순서이다.

이를 다시 연도별, 학제별 순위를 구한다면 다음과 같다.

df_비정규교원당학생수_rank <- df_비정규교원당학생수 |> group_by(연도, 학제) |>
  mutate(rank = rank(비정규교원당학생수))

df_비정규교원당학생수_rank |> arrange(rank) |>
  filter(rank == 1)
## # A tibble: 21 x 10
## # Groups:   연도, 학제 [21]
##    연도  시도  학제     학급수 학생수 전체교원수 기간제교원수 시간강사수
##    <chr> <chr> <chr>     <dbl>  <dbl>      <dbl>        <dbl>      <dbl>
##  1 2015  서울  중학교     9249 263466      18076         2642       1633
##  2 2015  부산  고등학교   3934 109773       8719         1546        118
##  3 2015  전남  초등학교   5041  94368       8026          385        105
##  4 2016  서울  중학교     9028 239912      17897         2727       1528
##  5 2016  부산  고등학교   3866 105793       8586         1594         99
##  6 2016  경북  초등학교   6242 127825      10016          567         94
##  7 2017  서울  중학교     8883 227001      17621         2680       1493
##  8 2017  부산  고등학교   3784  99662       8403         1612        121
##  9 2017  경북  초등학교   6211 127642      10021          584         78
## 10 2018  부산  중학교     3043  77021       6325         1145        428
## # ... with 11 more rows, and 2 more variables: 비정규교원당학생수 <dbl>,
## #   rank <dbl>

각 연도의 학제별 상위 3개의 데이터는 다음과 같다.

연도 시도 학제 학급수 학생수 전체교원수 기간제교원수 시간강사수 비정규교원당학생수 rank
2015 부산 고등학교 3934 109773 8719 1546 118 65.97 1
2015 서울 고등학교 10233 308306 22870 3619 648 72.25 2
2015 경기 고등학교 14388 444554 32996 5573 360 74.93 3
2015 서울 중학교 9249 263466 18076 2642 1633 61.63 1
2015 부산 중학교 3394 95020 6673 1049 370 66.96 2
2015 대구 중학교 2829 80982 5601 764 435 67.54 3
2015 전남 초등학교 5041 94368 8026 385 105 192.59 1
2015 경북 초등학교 6305 129743 10059 566 92 197.18 2
2015 경남 초등학교 8703 187075 13301 544 326 215.03 3
2016 부산 고등학교 3866 105793 8586 1594 99 62.49 1
2016 서울 고등학교 10096 299556 22598 3643 674 69.39 2
2016 경남 고등학교 4027 117575 9191 1363 229 73.85 3
2016 서울 중학교 9028 239912 17897 2727 1528 56.38 1
2016 울산 중학교 1305 35343 2730 511 93 58.51 2
2016 부산 중학교 3224 86650 6453 1031 394 60.81 3
2016 경북 초등학교 6242 127825 10016 567 94 193.38 1
2016 전남 초등학교 5005 92981 7968 316 89 229.58 2
2016 경남 초등학교 8742 185325 13425 487 293 237.60 3
2017 부산 고등학교 3784 99662 8403 1612 121 57.51 1
2017 서울 고등학교 9889 282968 22212 3755 622 64.65 2
2017 대전 고등학교 1842 53770 4300 661 132 67.81 3
2017 서울 중학교 8883 227001 17621 2680 1493 54.40 1
2017 울산 중학교 1255 32931 2673 493 84 57.07 2
2017 부산 중학교 3131 80719 6325 1009 401 57.25 3
2017 경북 초등학교 6211 127642 10021 584 78 192.81 1
2017 전남 초등학교 5032 93233 7965 333 65 234.25 2
2017 충남 초등학교 5767 116963 8914 467 27 236.77 3
2018 부산 고등학교 3651 90667 8248 1699 108 50.18 1
2018 광주 고등학교 1838 53891 4220 922 11 57.76 2
2018 서울 고등학교 9685 259554 21884 3891 594 57.87 3
2018 부산 중학교 3043 77021 6325 1145 428 48.96 1
2018 서울 중학교 8855 216330 17743 2836 1493 49.97 2
2018 경북 중학교 2820 63540 6387 945 195 55.74 3
2018 경북 초등학교 6291 129290 10168 570 77 199.83 1
2018 경기 초등학교 30119 752499 45201 3099 445 212.33 2
2018 충남 초등학교 5925 120152 9203 501 21 230.18 3
2019 부산 고등학교 3554 82132 8099 1845 91 42.42 1
2019 경북 고등학교 3211 71272 7164 1308 202 47.20 2
2019 광주 고등학교 1808 49048 4179 990 5 49.29 3
2019 서울 중학교 8770 207413 17596 2939 1363 48.21 1
2019 경북 중학교 2874 61393 6446 1076 183 48.76 2
2019 부산 중학교 2956 73338 6143 1146 340 49.35 3
2019 경기 초등학교 31148 769744 46568 4243 364 167.08 1
2019 울산 초등학교 2983 68512 4322 313 31 199.16 2
2019 경북 초등학교 6433 131374 10257 541 85 209.86 3
2020 부산 고등학교 3464 76573 7933 1903 75 38.71 1
2020 경북 고등학교 3182 66899 7212 1470 152 41.24 2
2020 광주 고등학교 1784 45612 4108 1020 12 44.20 3
2020 경북 중학교 2917 62499 6489 1179 157 46.78 1
2020 부산 중학교 2961 73749 6136 1282 242 48.39 2
2020 광주 중학교 1797 43415 3728 804 34 51.81 3
2020 경기 초등학교 31292 761731 46820 3819 258 186.84 1
2020 전남 초등학교 5183 92405 8290 392 86 193.32 2
2020 경북 초등학교 6407 129079 10324 542 75 209.20 3
2021 부산 고등학교 3453 73499 7817 2034 102 34.41 1
2021 경북 고등학교 3116 64967 7200 1541 206 37.19 2
2021 서울 고등학교 9194 216319 21039 4839 613 39.68 3
2021 부산 중학교 3016 75357 6176 1500 236 43.41 1
2021 경북 중학교 2968 63732 6587 1273 190 43.56 2
2021 서울 중학교 8563 209749 17234 3166 1057 49.67 3
2021 경북 초등학교 6428 127912 10586 720 54 165.26 1
2021 경기 초등학교 31670 763912 48013 4293 247 168.26 2
2021 전남 초등학교 5255 91229 8462 389 60 203.18 3

댓글