저번 포스팅에서 외식비 관련해서 지도 그래프를 하나만 그렸었었다. 그런데 외식비 통계에 보면 냉면, 비빔밥, 삽겹살 등 종류가 다양하기 때문에 종류별로 지도를 하나로 묶어 표현하는게 좋을거 같았다. shp 지도파일만 있으면 ggplot을 이용해서 여러 그래프를 한판에 그릴 수 있다.
데이터 준비
한국소비자원 외식비 가격정보 사이트에 가서 데이터를 다운받는다. 그리고 불필요한 데이터를 지워 정리한다.
excel_data = read_excel('~/data.xls') |>
select(1:5, 삼겹살 = 7, 8:10) |>
arrange(지역)
# A tibble: 16 × 9
번호 지역 냉면 비빔밥 김치찌개백반 삼겹살 자장면 삼계탕 칼국수
<chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr>
1 8 강원 9667 9722 8167 15321 6722 15667 8444
2 9 경기 10017 9128 7962 17507 6776 16414 8862
3 10 경남 10192 8500 8231 17944 6077 16077 7231
4 11 경북 9538 9154 8038 15796 5923 15000 7923
5 2 광주 9400 9900 8000 14844 6800 16400 8200
# ℹ 11 more rows
# ℹ Use `print(n = ...)` to see more rows
외식비 엑셀데이터에 지도데이터의 시도 코드를 매핑해서 추가한다.
all_data = excel_data |>
bind_cols(sido3 |> st_drop_geometry() |>
arrange(CTP_KOR_NM) |>
select(1))
# A tibble: 16 × 10
번호 지역 냉면 비빔밥 김치찌개백반 삼겹살 자장면 삼계탕 칼국수 CTPRVN_CD
<chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr>
1 8 강원 9667 9722 8167 15321 6722 15667 8444 51
2 9 경기 10017 9128 7962 17507 6776 16414 8862 41
3 10 경남 10192 8500 8231 17944 6077 16077 7231 48
4 11 경북 9538 9154 8038 15796 5923 15000 7923 47
5 2 광주 9400 9900 8000 14844 6800 16400 8200 29
# ℹ 11 more rows
# ℹ Use `print(n = ...)` to see more rows
CTPRVN_CD
필드를 둘다 가지고 있도록 미리 셋팅을 해놨기 때문에, left_join
을 이용하면 지도 데이터에 외식비 데이터를 쉽게 조인할 수 있다. 그런데, 이런 레이아웃으로는 효율적으로 여러개의 지도를 그리기 어렵다.
sido66 = sido3 |>
left_join(all_data, by = join_by(CTPRVN_CD))
# 출력결과
Simple feature collection with 16 features and 12 fields
Geometry type: GEOMETRY
Dimension: XY
Bounding box: xmin: 747235.2 ymin: 1468717 xmax: 1391920 ymax: 2065895
Projected CRS: Korea 2000 / Unified CS
# A tibble: 16 × 13
CTPRVN_CD CTP_KOR_NM CTP_ENG_NM geometry 번호 지역 냉면 비빔밥 김치찌개백반
<chr> <chr> <chr> <GEOMETRY [m]> <chr> <chr> <chr> <chr> <chr>
1 11 서울특별시 Seoul POLYGON ((966793.7 19408… 1 서울 11308 10577 8000
2 26 부산광역시 Busan MULTIPOLYGON (((1137147 … 5 부산 10714 8814 7714
3 27 대구광역시 Daegu POLYGON ((1087860 176009… 3 대구 10417 9367 7150
4 28 인천광역시 Incheon MULTIPOLYGON (((905900.6… 7 인천 10667 8833 7333
5 29 광주광역시 Gwangju POLYGON ((932781.7 16961… 2 광주 9400 9900 8000
6 30 대전광역시 Daejeon POLYGON ((991177.8 18321… 4 대전 10600 9800 9300
7 31 울산광역시 Ulsan POLYGON ((1161481 170970… 6 울산 10000 9700 8000
8 41 경기도 Gyeonggi-… POLYGON ((937517.7 18908… 9 경기 10017 9128 7962
9 43 충청북도 Chungcheo… POLYGON ((1063153 191651… 15 충북 8929 9171 8357
10 44 충청남도 Chungcheo… MULTIPOLYGON (((904505.9… 14 충남 9500 9500 8500
11 45 전라북도 Jeollabuk… POLYGON ((921372.9 17760… 13 전북 9200 11290 8600
12 46 전라남도 Jellanam-… MULTIPOLYGON (((916440.3… 12 전남 8778 8500 7500
13 47 경상북도 Gyeongsan… MULTIPOLYGON (((1187259 … 11 경북 9538 9154 8038
14 48 경상남도 Gyeongsan… MULTIPOLYGON (((1080160 … 10 경남 10192 8500 8231
15 50 제주특별자치… Jeju-do POLYGON ((883486.3 14703… 16 제주 9000 9750 9125
16 51 강원특별자치… Gangwon-do POLYGON ((1157807 192532… 8 강원 9667 9722 8167
# ℹ 4 more variables: 삼겹살 <chr>, 자장면 <chr>, 삼계탕 <chr>, 칼국수 <chr>
횡으로 펼쳐져있던 외식비종류를 아래방향으로 내려야 한다. pivot_longer
을 이용하면 아래와 같이 데이터 형태가 변환된다.
sido77 = sido66 |>
pivot_longer(냉면:삼계탕) |>
mutate(value = as.numeric(value))
# 출력결과
Simple feature collection with 96 features and 8 fields
Geometry type: GEOMETRY
Dimension: XY
Bounding box: xmin: 747235.2 ymin: 1468717 xmax: 1391920 ymax: 2065895
Projected CRS: Korea 2000 / Unified CS
# A tibble: 96 × 9
CTPRVN_CD CTP_KOR_NM CTP_ENG_NM geometry 번호 지역 칼국수 name value
* <chr> <chr> <chr> <GEOMETRY [m]> <chr> <chr> <chr> <chr> <dbl>
1 11 서울특별시 Seoul POLYGON ((966793.7 1940892, 967160… 1 서울 8962 냉면 11308
2 11 서울특별시 Seoul POLYGON ((966793.7 1940892, 967160… 1 서울 8962 비빔… 10577
3 11 서울특별시 Seoul POLYGON ((966793.7 1940892, 967160… 1 서울 8962 김치… 8000
4 11 서울특별시 Seoul POLYGON ((966793.7 1940892, 967160… 1 서울 8962 삼겹… 19429
5 11 서울특별시 Seoul POLYGON ((966793.7 1940892, 967160… 1 서울 8962 자장… 7069
6 11 서울특별시 Seoul POLYGON ((966793.7 1940892, 967160… 1 서울 8962 삼계… 16846
7 26 부산광역시 Busan MULTIPOLYGON (((1137147 1677385, 1… 5 부산 7200 냉면 10714
8 26 부산광역시 Busan MULTIPOLYGON (((1137147 1677385, 1… 5 부산 7200 비빔… 8814
9 26 부산광역시 Busan MULTIPOLYGON (((1137147 1677385, 1… 5 부산 7200 김치… 7714
10 26 부산광역시 Busan MULTIPOLYGON (((1137147 1677385, 1… 5 부산 7200 삼겹… 15830
# ℹ 86 more rows
# ℹ Use `print(n = ...)` to see more rows
facet_wrap
을 사용하여 여러지도를 하나의 plot 안에 그릴 수 있다. 그런데 이 데이터를 기준으로 ggplot2 를 그리면, 생각했던 것과는 다른 결과가 출력된다. 냉면 외식비의 최소,최대값을 기준으로 색이 채워져야 하는데, 전체 금액에서 냉면이 차지하는 범위만큼의 색만 사용되고 있었다.
ggplot(data = sido77) +
geom_sf(aes(fill = value)) +
scale_fill_viridis_c(option = "B", begin = 0.4, direction = -1) +
facet_wrap(vars(name))
min-max 스케일로 0~1사이값으로 조정
이럴때는 최소값과 최대값을 가지고 0~1 값으로 리스케일 작업을 해야 한다.
sido88 = sido77 |>
group_by(name) |>
mutate(min_value = min(value),
max_value = max(value)) |>
mutate(norm = (value - min_value) / (max_value - min_value))
Simple feature collection with 6 features and 11 fields
Geometry type: POLYGON
Dimension: XY
Bounding box: xmin: 935186.2 ymin: 1936868 xmax: 971969.6 ymax: 1966536
Projected CRS: Korea 2000 / Unified CS
# A tibble: 6 × 12
# Groups: name [6]
CTPRVN_CD CTP_KOR_NM CTP_ENG_NM geometry 번호 지역 칼국수 name value min_value
<chr> <chr> <chr> <POLYGON [m]> <chr> <chr> <chr> <chr> <dbl> <dbl>
1 11 서울특별시 Seoul ((966793.7 1940892, 96716… 1 서울 8962 냉면 11308 8778
2 11 서울특별시 Seoul ((966793.7 1940892, 96716… 1 서울 8962 비빔… 10577 8500
3 11 서울특별시 Seoul ((966793.7 1940892, 96716… 1 서울 8962 김치… 8000 7150
4 11 서울특별시 Seoul ((966793.7 1940892, 96716… 1 서울 8962 삼겹… 19429 14197
5 11 서울특별시 Seoul ((966793.7 1940892, 96716… 1 서울 8962 자장… 7069 5923
6 11 서울특별시 Seoul ((966793.7 1940892, 96716… 1 서울 8962 삼계… 16846 14714
# ℹ 2 more variables: max_value <dbl>, norm <dbl>
그러면 제대로 색이 더 대비되어 출력된다. 빨간색이 짙을수록 비싼 물가 지역이고, 엻은색일 수록 저렴한 지역으로 표현하였다.
ggplot(data = sido88) +
geom_sf(aes(fill = norm)) +
scale_fill_viridis_c(option = "B", begin = 0.4, direction = -1) +
coord_sf(datum = st_crs(5179)) +
facet_wrap(vars(name))