웹R의 운영자 문건웅입니다. 2014년 한국행정지도를 이용하여 단계구분도를 쉽게 만들 수 있게 해 주는 kormaps2014 패키지를 소개합니다. Shape데이타를 데이타프레임으로 미리 변환하였으므로 ggplot2등을 이용하여 쉽게 단계구분도를 그릴 수 있습니다.
제가 만든 다른 패키지 moonBook2에 있는 ggChoropleth()함수를 이용하면 보다 쉽게 단계구분도를 그릴 수 있습니다. static image뿐만 아니라 tooltip 사용 및 축소 확대 가능한 interactive plot도 쉽게 그릴 수 있습니다.
kormaps패키지는 github에 있습니다. CRAN에 올릴 수는 있으나 한글을 모두 unicode로 변환해야 해서 사용하기 번거로와 github에 올렸습니다. github에 있는 패키지를 설치하려면 devtools 패키지에 있는 install_github()함수를 사용합니다.
install.packages("devtools")
devtools::install_github("cardiomoon/kormaps2014")
moonBook2패키지를 설치하시려면 다음과 같이 합니다. 처음 설치하는 경우 많은 패키지를 설치하므로 시간이 조금 걸립니다.
devtools::install_github("cardiomoon/moonBook2")
패키지를 사용하려면 다음과 같이 패키지를 불러옵니다.
library(kormaps2014)
library(moonBook2)
kormaps 패키지에는 areacode, kormap1, kormap2, kormap3, korpop1, korpop2, korpop3, tbc데이타가 포함되어 있습니다.
areacode
code name name1
1 11 서울특별시 서울
2 21 부산광역시 부산
3 22 대구광역시 대구
4 23 인천광역시 인천
5 24 광주광역시 광주
6 25 대전광역시 대전
7 26 울산광역시 울산
8 29 세종특별자치시 세종
9 31 경기도 경기
10 32 강원도 강원
11 33 충청북도 충북
12 34 충청남도 충남
13 35 전라북도 전북
14 36 전라남도 전남
15 37 경상북도 경북
16 38 경상남도 경남
17 39 제주특별자치도 제주
str(kormap1)
'data.frame': 8831 obs. of 15 variables:
$ id : chr "0" "0" "0" "0" ...
$ long : num 138 138 138 138 138 ...
$ lat : num 50.7 50.7 50.7 50.7 50.7 ...
$ order : int 1 2 3 4 5 6 7 8 9 10 ...
$ hole : logi FALSE FALSE FALSE FALSE FALSE FALSE ...
$ piece : Factor w/ 113 levels "1","2","3","4",..: 1 1 1 1 1 1 1 1 1 1 ...
$ group : Factor w/ 205 levels "0.1","1.1","1.2",..: 1 1 1 1 1 1 1 1 1 1 ...
$ SP_ID : Factor w/ 17 levels "0","1","10","11",..: 1 1 1 1 1 1 1 1 1 1 ...
$ SIDO_CD : Factor w/ 17 levels "11","21","22",..: 1 1 1 1 1 1 1 1 1 1 ...
$ SIDO_NM : Factor w/ 17 levels "\xb0\xad\xbf\xf8\xb5\xb5",..: 9 9 9 9 9 9 9 9 9 9 ...
$ BASE_YEAR: Factor w/ 1 level "2014": 1 1 1 1 1 1 1 1 1 1 ...
$ name : Factor w/ 17 levels "강원도","경기도",..: 9 9 9 9 9 9 9 9 9 9 ...
$ name1 : Factor w/ 17 levels "\xb0\xad\xbf\xf8\xb5\xb5",..: 9 9 9 9 9 9 9 9 9 9 ...
$ region : Factor w/ 17 levels "11","21","22",..: 1 1 1 1 1 1 1 1 1 1 ...
$ code : Factor w/ 17 levels "11","21","22",..: 1 1 1 1 1 1 1 1 1 1 ...
str(kormap2)
'data.frame': 20397 obs. of 15 variables:
$ id : chr "0" "0" "0" "0" ...
$ long : num 138 138 138 138 138 ...
$ lat : num 50.6 50.6 50.6 50.6 50.6 ...
$ order : int 1 2 3 4 5 6 7 8 9 10 ...
$ hole : logi FALSE FALSE FALSE FALSE FALSE FALSE ...
$ piece : Factor w/ 39 levels "1","2","3","4",..: 1 1 1 1 1 1 1 1 1 1 ...
$ group : Factor w/ 414 levels "0.1","1.1","2.1",..: 1 1 1 1 1 1 1 1 1 1 ...
$ SP_ID : Factor w/ 252 levels "0","1","10","100",..: 1 1 1 1 1 1 1 1 1 1 ...
$ base_year : Factor w/ 1 level "2014": 1 1 1 1 1 1 1 1 1 1 ...
$ sigungu_cd: Factor w/ 252 levels "11010","11020",..: 1 1 1 1 1 1 1 1 1 1 ...
$ sigungu_nm: Factor w/ 229 levels "\xb0\xa1\xc6\xf2\xb1\xba",..: 182 182 182 182 182 182 182 182 182 182 ...
$ name : Factor w/ 229 levels "가평군","강남구",..: 180 180 180 180 180 180 180 180 180 180 ...
$ name1 : Factor w/ 229 levels "\xb0\xa1\xc6\xf2\xb1\xba",..: 182 182 182 182 182 182 182 182 182 182 ...
$ region : Factor w/ 252 levels "11010","11020",..: 1 1 1 1 1 1 1 1 1 1 ...
$ code : Factor w/ 252 levels "11010","11020",..: 1 1 1 1 1 1 1 1 1 1 ...
str(kormap3)
'data.frame': 73474 obs. of 15 variables:
$ id : chr "0" "0" "0" "0" ...
$ long : num 138 138 138 138 138 ...
$ lat : num 50.6 50.6 50.6 50.6 50.6 ...
$ order : int 1 2 3 4 5 6 7 8 9 1 ...
$ hole : logi FALSE FALSE FALSE FALSE FALSE FALSE ...
$ piece : Factor w/ 10 levels "1","2","3","4",..: 1 1 1 1 1 1 1 1 1 1 ...
$ group : Factor w/ 3621 levels "0.1","1.1","2.1",..: 1 1 1 1 1 1 1 1 1 2 ...
$ SP_ID : Factor w/ 3488 levels "0","1","10","100",..: 1 1 1 1 1 1 1 1 1 2 ...
$ base_year: Factor w/ 1 level "2014": 1 1 1 1 1 1 1 1 1 1 ...
$ adm_dr_cd: Factor w/ 3488 levels "1101053","1101054",..: 1 1 1 1 1 1 1 1 1 2 ...
$ adm_dr_nm: Factor w/ 3128 levels "÷\xb4\xdc1\xb5\xbf",..: 1259 1259 1259 1259 1259 1259 1259 1259 1259 1320 ...
$ name : Factor w/ 3128 levels "가경동","가곡동",..: 1266 1266 1266 1266 1266 1266 1266 1266 1266 1338 ...
$ name1 : Factor w/ 3128 levels "÷\xb4\xdc1\xb5\xbf",..: 1259 1259 1259 1259 1259 1259 1259 1259 1259 1320 ...
$ region : Factor w/ 3488 levels "1101053","1101054",..: 1 1 1 1 1 1 1 1 1 2 ...
$ code : Factor w/ 3488 levels "1101053","1101054",..: 1 1 1 1 1 1 1 1 1 2 ...
1.korpop1 : 2015년 센서스데이터(시도별) 2.korpop2 : 2015년 센서스데이터(시군구별) 3.korpop3 : 2015년 센서스데이터(읍면동)
str(korpop1)
'data.frame': 17 obs. of 25 variables:
$ C행정구역별_읍면동 : Factor w/ 3819 levels "'00","'03","'04",..: 5 455 681 832 995 1096 1181 1246 1264 1874 ...
$ 행정구역별_읍면동 : Factor w/ 3398 levels " 가경동"," 가곡동",..: 3388 3387 3383 3392 3382 3384 3390 3389 3379 3378 ...
$ 시점 : int 2015 2015 2015 2015 2015 2015 2015 2015 2015 2015 ...
$ 총인구_명 : int 9904312 3448737 2466052 2890451 1502881 1538394 1166615 204088 12479061 1518040 ...
$ 남자_명 : int 4859535 1701347 1228511 1455017 748867 772243 606924 103210 6309661 768241 ...
$ 여자_명 : int 5044777 1747390 1237541 1435434 754014 766151 559691 100878 6169400 749799 ...
$ 내국인_계_명 : int 9567196 3404667 2436770 2822601 1481289 1519314 1136755 199617 12026429 1499734 ...
$ 내국인_남자_명 : int 4694317 1675339 1211219 1414793 736656 763310 587603 100455 6039800 758601 ...
$ 내국인_여자_명 : int 4872879 1729328 1225551 1407808 744633 756004 549152 99162 5986629 741133 ...
$ 외국인_계_명 : Factor w/ 1256 levels "10","100","1009",..: 618 764 554 1024 394 330 563 772 781 306 ...
$ 외국인_남자_명 : Factor w/ 995 levels "10","100","1002",..: 200 388 224 589 82 952 262 413 401 985 ...
$ 외국인_여자_명 : Factor w/ 856 levels "10","100","1000",..: 174 189 66 350 840 8 25 173 196 812 ...
$ 가구_계_가구 : int 3914820 1348315 937573 1066297 573181 588395 434058 76419 4537581 611578 ...
$ 일반가구_가구 : int 3784490 1335900 928528 1045417 567157 582504 423412 75219 4384742 606117 ...
$ 집단가구_가구 : Factor w/ 176 levels "10","100","102",..: 64 143 129 148 109 104 68 139 99 155 ...
$ 외국인가구_가구 : Factor w/ 764 levels "10","100","10002",..: 75 46 709 214 579 574 15 35 126 523 ...
$ 주택_계_호 : int 2793244 1164352 738100 942244 486527 468885 357674 81130 3693557 569899 ...
$ 단독주택_호 : Factor w/ 2149 levels "100","1000","1001",..: 1443 1090 594 34 2019 1941 1777 606 1614 1122 ...
$ 아파트_호 : Factor w/ 2466 levels "10","100","10008",..: 517 2103 1622 1787 1281 1161 879 1886 873 1031 ...
$ 연립주택_호 : Factor w/ 875 levels "10","100","1002",..: 54 424 857 266 773 4 782 874 67 241 ...
$ 다세대주택_호 : Factor w/ 1428 levels "10","100","1000",..: 1192 269 1064 551 1331 803 580 251 1073 60 ...
$ 비거주용_건물내_주택_호: Factor w/ 534 levels "10","100","1001",..: 279 94 17 473 391 384 421 431 294 19 ...
$ 주택이외의_거처_호 : Factor w/ 911 levels "10","100","1007",..: 159 643 167 550 26 27 805 295 200 84 ...
$ C행정구역별 : chr "11" "21" "22" "23" ...
$ code : chr "11" "21" "22" "23" ...
str(korpop2)
'data.frame': 306 obs. of 25 variables:
$ C행정구역별_읍면동 : Factor w/ 3819 levels "'00","'03","'04",..: 6 24 40 57 75 91 106 123 144 158 ...
$ 행정구역별_읍면동 : Factor w/ 3398 levels " 가경동"," 가곡동",..: 3331 3332 3300 3247 3163 3202 3333 3248 3140 3199 ...
$ 시점 : int 2015 2015 2015 2015 2015 2015 2015 2015 2015 2015 ...
$ 총인구_명 : int 161521 128478 227282 295006 368199 364787 403237 456844 319992 340095 ...
$ 남자_명 : int 79510 63218 109980 146332 180647 181189 199936 221861 156386 166187 ...
$ 여자_명 : int 82011 65260 117302 148674 187552 183598 203301 234983 163606 173908 ...
$ 내국인_계_명 : int 146119 118021 212189 285137 350993 349957 397487 445710 315754 337541 ...
$ 내국인_남자_명 : int 71951 58223 102154 141429 172622 174710 197499 216872 154667 165130 ...
$ 내국인_여자_명 : int 74168 59798 110035 143708 178371 175247 199988 228838 161087 172411 ...
$ 외국인_계_명 : Factor w/ 1256 levels "10","100","1009",..: 225 20 212 1244 276 198 925 58 740 485 ...
$ 외국인_남자_명 : Factor w/ 995 levels "10","100","1002",..: 886 706 901 696 914 814 361 704 220 21 ...
$ 외국인_여자_명 : Factor w/ 856 levels "10","100","1000",..: 774 637 748 594 833 801 427 687 316 130 ...
$ 가구_계_가구 : int 68429 55508 96385 118900 155242 153362 160043 178717 127462 125952 ...
$ 일반가구_가구 : int 61580 51205 90313 114719 147718 146677 157537 174257 125666 124981 ...
$ 집단가구_가구 : Factor w/ 176 levels "10","100","102",..: 6 137 142 151 163 28 142 46 161 137 ...
$ 외국인가구_가구 : Factor w/ 764 levels "10","100","10002",..: 642 488 602 474 676 632 276 495 160 730 ...
$ 주택_계_호 : int 43550 37478 70723 82331 79393 98203 99265 128046 91806 102443 ...
$ 단독주택_호 : Factor w/ 2149 levels "100","1000","1001",..: 335 1756 585 137 734 997 1020 1276 907 2083 ...
$ 아파트_호 : Factor w/ 2466 levels "10","100","10008",..: 263 778 1209 1822 1037 1827 1605 2040 1124 1923 ...
$ 연립주택_호 : Factor w/ 875 levels "10","100","1002",..: 649 230 517 250 558 485 606 725 600 540 ...
$ 다세대주택_호 : Factor w/ 1428 levels "10","100","1000",..: 102 1155 265 1336 639 144 489 543 794 570 ...
$ 비거주용_건물내_주택_호: Factor w/ 534 levels "10","100","1001",..: 488 451 424 14 105 130 119 115 22 442 ...
$ 주택이외의_거처_호 : Factor w/ 911 levels "10","100","1007",..: 573 500 556 600 620 764 368 431 271 389 ...
$ C행정구역별 : chr "11010" "11020" "11030" "11040" ...
$ code : chr "11010" "11020" "11030" "11040" ...
str(korpop3)
'data.frame': 3492 obs. of 25 variables:
$ C행정구역별_읍면동 : Factor w/ 3819 levels "'00","'03","'04",..: 7 8 9 10 11 12 13 14 15 16 ...
$ 행정구역별_읍면동 : Factor w/ 3398 levels " 가경동"," 가곡동",..: 1273 1345 1177 2863 920 282 45 2540 2541 2342 ...
$ 시점 : int 2015 2015 2015 2015 2015 2015 2015 2015 2015 2015 ...
$ 총인구_명 : int 9379 2808 11012 18594 8106 4620 4917 7598 5792 9519 ...
$ 남자_명 : int 4325 1340 5327 8794 3829 2234 2417 4130 3128 4505 ...
$ 여자_명 : int 5054 1468 5685 9800 4277 2386 2500 3468 2664 5014 ...
$ 내국인_계_명 : int 8571 2601 10157 17789 7981 4441 4616 6679 5169 8618 ...
$ 내국인_남자_명 : int 3934 1222 4921 8393 3785 2133 2267 3699 2837 4022 ...
$ 내국인_여자_명 : int 4637 1379 5236 9396 4196 2308 2349 2980 2332 4596 ...
$ 외국인_계_명 : Factor w/ 1256 levels "10","100","1009",..: 1121 372 1157 1120 118 294 569 1199 970 1186 ...
$ 외국인_남자_명 : Factor w/ 995 levels "10","100","1002",..: 574 66 592 587 634 5 159 623 436 687 ...
$ 외국인_여자_명 : Factor w/ 856 levels "10","100","1000",..: 524 820 549 505 787 773 134 585 428 525 ...
$ 가구_계_가구 : int 3897 1168 4096 6645 2871 1947 1964 4122 2683 4383 ...
$ 일반가구_가구 : int 3562 1092 3841 6310 2823 1888 1843 3733 2376 3981 ...
$ 집단가구_가구 : Factor w/ 176 levels "10","100","102",..: 145 176 132 40 176 176 176 47 176 157 ...
$ 외국인가구_가구 : Factor w/ 764 levels "10","100","10002",..: 387 677 285 379 525 588 50 432 363 457 ...
$ 주택_계_호 : int 2771 799 2957 5754 2870 1527 1646 1613 1116 2725 ...
$ 단독주택_호 : Factor w/ 2149 levels "100","1000","1001",..: 1849 1830 101 569 635 1209 1873 1681 1892 1935 ...
$ 아파트_호 : Factor w/ 2466 levels "10","100","10008",..: 460 2466 217 2395 905 134 2466 2390 22 617 ...
$ 연립주택_호 : Factor w/ 875 levels "10","100","1002",..: 793 217 842 271 656 832 106 365 875 345 ...
$ 다세대주택_호 : Factor w/ 1428 levels "10","100","1000",..: 880 917 1303 27 1033 42 1254 628 1366 213 ...
$ 비거주용_건물내_주택_호: Factor w/ 534 levels "10","100","1001",..: 360 242 317 414 108 534 160 423 112 438 ...
$ 주택이외의_거처_호 : Factor w/ 911 levels "10","100","1007",..: 728 492 262 109 251 374 658 102 488 226 ...
$ C행정구역별 : chr "1101053" "1101054" "1101055" "1101056" ...
$ code : chr "1101053" "1101054" "1101055" "1101056" ...
다음으로는 ggplot2를 이용한 단계구분도를 그려보겠습니다. 2015년 인구총조사 중 “총인구_명”으로 단계구분도를 그리려면 다음과 같이 합니다.
library(ggplot2)
theme_set(theme_gray(base_family="NanumGothic"))
ggplot(korpop1,aes(map_id=code,fill=총인구_명))+
geom_map(map=kormap1,colour="black",size=0.1)+
expand_limits(x=kormap1$long,y=kormap1$lat)+
scale_fill_gradientn(colours=c('white','orange','red'))+
ggtitle("2015년도 시도별 인구분포도")+
coord_map()
moonBook2패키지에 있는 ggChoropleth()함수를 이용하면 훨씬 간편하게 단계구분도를 그릴 수 있습니다. 다음은 시군구별, 읍면동별 단계구분도의 예제입니다.
ggChoropleth(korpop2,kormap2,fillvar="남자_명")
ggChoropleth(korpop3,kormap3,fillvar="주택_계_호")
ggChoropleth()함수의 subarea인수를 이용하면 지도의 일부를 쉽게 그릴 수 있습니다. 예를 들어 호남지방의 단계구분도만 그리려면 다음과같이 할수 있습니다.
ggChoropleth(korpop3,kormap3,fillvar="총인구_명",subarea=c("전라","광주"))
ggChoropleth함수는 내부적으로 ggiraph()패키지를 이용하여 interactive plot을 쉽게 만들어줍니다. interactive인수를 TRUE로 설정하면 됩니다. 이 plot은 마우스 휠을 사용하여 축소 확대도 가능하고 tooltip도 보여줍니다.
ggChoropleth(korpop2,kormap2,fillvar="남자_명",interactive=TRUE)
하지만 tooltip에 보이는 것이 행정구역코드가 보입니다. tooltip으로 행정구역 코드가 아닌 행정구역명을 보이게 하려면 tooltip인수에 지정해주면 됩니다.
ggChoropleth(korpop3,kormap3,fillvar="남자_명",interactive=TRUE,subarea=c("전라","광주"),tooltip="행정구역별_읍면동")
tbc는 국가통계포털(kosis.kr) 에 공개되어 있는 시도별 결핵신환 발생 데이터를 long form으로 변환한 데이터입니다. 구조는 다음과 같습니다.
summary(tbc)
name1 code name year
강원 : 15 Min. :11.00 강원도 : 15 2001 : 17
경기 : 15 1st Qu.:24.00 경기도 : 15 2002 : 17
경남 : 15 Median :31.00 경상남도 : 15 2003 : 17
경북 : 15 Mean :29.18 경상북도 : 15 2004 : 17
광주 : 15 3rd Qu.:35.00 광주광역시: 15 2005 : 17
대구 : 15 Max. :39.00 대구광역시: 15 2006 : 17
(Other):165 (Other) :165 (Other):153
NewPts
Min. : 71.0
1st Qu.: 892.8
Median : 1394.5
Mean : 2140.2
3rd Qu.: 2217.0
Max. :11178.0
NA's :11
이 데이타 중 2001,2005,2010,2015 만 이용하려면 다음과 같이 하면 됩니다.
tbc1=tbc[tbc$year %in% c(2001,2005,2010,2015),]
이 데이타로 년도별로 면 분할된 단계구분도를 그리면 다음과 같이 합니다
ggChoropleth(tbc1,kormap1,fillvar="NewPts",facetvar="year",tooltip="name",interactive=TRUE)
2001년-2010년에는 서울의 결핵신환 발생이 전국에서 가장 많았지만 2015년에는 서울의 결핵신환 발생수가 경기도보다 적음을 알 수 있습니다.
kormaps2014 패키지의 한글데이타는 “UTF-8”로 되어 있습니다. 윈도우 사용자는 이를 “CP-949”로 바꾸어주어야 합니다. 이를 위해 changeCode()함수를 제공합니다. changeCode함수는 한글 코드를 “CP-949”로 바꾸어 줍니다.
areacode
code name name1
1 11 서울특별시 서울
2 21 부산광역시 부산
3 22 대구광역시 대구
4 23 인천광역시 인천
5 24 광주광역시 광주
6 25 대전광역시 대전
7 26 울산광역시 울산
8 29 세종특별자치시 세종
9 31 경기도 경기
10 32 강원도 강원
11 33 충청북도 충북
12 34 충청남도 충남
13 35 전라북도 전북
14 36 전라남도 전남
15 37 경상북도 경북
16 38 경상남도 경남
17 39 제주특별자치도 제주
areacode1=changeCode(areacode)
areacode1
code name name1
1 11 \xbc\xad\xbf\xefƯ\xba\xb0\xbd\xc3 \xbc\xad\xbf\xef
2 21 \xbaλ걤\xbf\xaa\xbd\xc3 \xbaλ\xea
3 22 \xb4뱸\xb1\xa4\xbf\xaa\xbd\xc3 \xb4뱸
4 23 \xc0\xceõ\xb1\xa4\xbf\xaa\xbd\xc3 \xc0\xceõ
5 24 \xb1\xa4\xc1ֱ\xa4\xbf\xaa\xbd\xc3 \xb1\xa4\xc1\xd6
6 25 \xb4\xeb\xc0\xfc\xb1\xa4\xbf\xaa\xbd\xc3 \xb4\xeb\xc0\xfc
7 26 \xbf\xef\xbb걤\xbf\xaa\xbd\xc3 \xbf\xef\xbb\xea
8 29 \xbc\xbc\xc1\xbeƯ\xba\xb0\xc0\xdaġ\xbd\xc3 \xbc\xbc\xc1\xbe
9 31 \xb0\xe6\xb1\u2d75 \xb0\xe6\xb1\xe2
10 32 \xb0\xad\xbf\xf8\xb5\xb5 \xb0\xad\xbf\xf8
11 33 \xc3\xe6û\xbaϵ\xb5 \xc3\xe6\xba\xcf
12 34 \xc3\xe6û\xb3\xb2\xb5\xb5 \xc3泲
13 35 \xc0\xfc\xb6\xf3\xbaϵ\xb5 \xc0\xfc\xba\xcf
14 36 \xc0\xfc\xb6\xb5 \xc0\xfc\xb3\xb2
15 37 \xb0\xe6\xbb\xf3\xbaϵ\xb5 \xb0\xe6\xba\xcf
16 38 \xb0\xe6\xbb\xb5 \xb0泲
17 39 \xc1\xa6\xc1\xd6Ư\xba\xb0\xc0\xdaġ\xb5\xb5 \xc1\xa6\xc1\xd6
윈도우 사용자가 지도 데이타를 사용하고자 할때에는 changeCode()함수로 한글코드를 바꾸어 사용하시기 바랍니다. 단 interactive plot을 사용할 때에는 변환하시지 말고 사용하셔야 합니다.