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 |
'데이터 전처리' 카테고리의 다른 글
탐색적 데이터 분석(Exploratory Data Analysis)의 자동화 패키지 in R - Part 2 : explore (0) | 2022.09.15 |
---|---|
탐색적 데이터 분석(Exploratory Data Analysis)의 자동화 패키지 in R - Part 1 : SmartEDA (0) | 2022.09.14 |
행정구역별 연령별 학생 비율 구하기 in R - mutate_all, mutate_at, mutate_if (0) | 2022.07.13 |
누적합과 누적평균 in R (0) | 2022.06.26 |
열 이름 바꾸기 in R (0) | 2022.06.21 |
댓글