(ggplot2) 지도에서 지역별 경계 합치기

한국소비자원에서 외식비 관련 통계를 가지고 지도그래프를 그릴까 했는데, 데이터에 세종시가 없었다. 내가 받은 shp 지도파일은 세종시가 별도로 있다보니, 충남지역에 넣어 경계를 합쳐야만 했다. sf 패키지에서는 영역을 합칠때, st_union 을 사용하면 된다. (ggplot2) 벤다이어그램 그리기 포스팅에 사용법을 정리해놓았다.

충청남도 지도 그리기

R프로그래밍 - ggplot 한국지도 그리기 포스팅에 지도데이터 다운로드 방법이 있으니 참고하시고, 시도 기준의 지도데이터를 불러온다.

sido = read_sf('~/map/sido_20230729/ctprvn.shp') |> 
    mutate(CTP_KOR_NM = iconv(CTP_KOR_NM, from = "EUC-KR", to = 'UTF-8')) |> 
    ms_simplify(keep = 0.001, keep_shapes = T)  |> 
    st_set_crs(5179)

그 중에 충청남도와 세종특별자치시만 따로 분리한다.

sido1 = sido |> 
  filter(CTPRVN_CD == '36' | CTPRVN_CD == '44')

# 출력결과
Simple feature collection with 2 features and 3 fields
Geometry type: GEOMETRY
Dimension:     XY
Bounding box:  xmin: 877217.3 ymin: 1776273 xmax: 1012454 ymax: 1895387
Projected CRS: Korea 2000 / Unified CS
# A tibble: 2 × 4
  CTPRVN_CD CTP_KOR_NM     CTP_ENG_NM                                                   geometry
* <chr>     <chr>          <chr>                                                  <GEOMETRY [m]>
1 36        세종특별자치시 Sejong-si         POLYGON ((973918 1857947, 969610.8 1859476, 9673432 44        충청남도       Chungcheongnam-do MULTIPOLYGON (((947410 1878304, 943219.1 1875900,

그 데이터로 지도를 그리면, 충청남도와 세종시의 지도만 그려진다. 작은 영역이 세종시이다.

ggplot() +
  geom_sf(data = sido1, aes(fill = CTPRVN_CD))

세종시를 충청남도에 포함시키기

우선 충청남도와 세종시를 각각 변수에 담아놓는다.

# 44.충청남도
sido44 = sido |> filter(CTPRVN_CD == '44')

# 36.세종특별자치시
sido36 = sido |> filter(CTPRVN_CD == '36')

st_geometry로 각각의 geometry 를 꺼내서, st_union 으로 합친다. 이렇게 되면 2개의 구역이 하나의 경계로 합쳐진다.

geom_sido44_2 = st_union(st_geometry(sido44), st_geometry(sido36))

# 출력결과
Geometry set for 1 feature 
Geometry type: MULTIPOLYGON
Dimension:     XY
Bounding box:  xmin: 877217.3 ymin: 1776273 xmax: 1012454 ymax: 1895387
Projected CRS: Korea 2000 / Unified CS
MULTIPOLYGON (((980180.2 1816403, 978436.9 1814...

합쳐진 geometry 를 충청남도 sf 데이터에 넣어준다.

sido44_2 = st_set_geometry(sido44, geom_sido44_2)

# 출력결과
Simple feature collection with 1 feature and 3 fields
Geometry type: MULTIPOLYGON
Dimension:     XY
Bounding box:  xmin: 877217.3 ymin: 1776273 xmax: 1012454 ymax: 1895387
Projected CRS: Korea 2000 / Unified CS
# A tibble: 1 × 4
  CTPRVN_CD CTP_KOR_NM CTP_ENG_NM                                                       geometry
* <chr>     <chr>      <chr>                                                  <MULTIPOLYGON [m]>
1 44        충청남도   Chungcheongnam-do (((980180.2 1816403, 978436.9 1814458, 978334.7 180877

그래프를 그려서 확인해보면, 세종시가 충청남도에 포함되도록 병합된게 보인다.

ggplot() +
  geom_sf(data = sido44_2, aes(fill = CTPRVN_CD))

나중에 안 사실인데, dplyr 패키지를 이용해서 group_by 해서 summarise 하면 지도 영역이 합쳐진다. 아래처럼도 구현이 가능하니 참고한다.

sido3 = sido |> 
  filter(CTPRVN_CD == '36' | CTPRVN_CD == '44') |> 
  summarise(CTPRVN_CD = '44') |> 
  left_join(st_drop_geometry(sido), by = join_by(CTPRVN_CD)) |> 
  select(1, 3:4, 2)

전국지도 기준으로 세종시를 충남에 포함하기 전과 후의 그림이다.

마지막으로 ‘23.12월기준 외식비 가격 통계를 가지고 지도그래프를 그려보았다.


더 보면 좋을 글들