---
title: "지도제작 대회"
subtitle: "인터랙티브 지도(Mapview)"
description: |
인터랙티브 지도를 제작해보자.
author:
- name: 이광춘
url: https://www.linkedin.com/in/kwangchunlee/
affiliation: 한국 R 사용자회
affiliation-url: https://github.com/bit2r
title-block-banner: true
format:
html:
theme: flatly
code-fold: true
code-overflow: wrap
toc: true
toc-depth: 3
toc-title: 목차
number-sections: true
highlight-style: github
self-contained: false
default-image-extension: jpg
filters:
- lightbox
lightbox: auto
link-citations: true
knitr:
opts_chunk:
message: false
warning: false
collapse: true
comment: "#>"
R.options:
knitr.graphics.auto_pdf: true
editor_options:
chunk_output_type: console
---
:::{.callout-tip}
### 소스코드
[ FelixAnalytix/YouTube ](https://github.com/FelixAnalytix/YouTube)
:::
# 패키지
```{r}
#| eval: true
if (! require ("tidyverse" )) install.packages ("tidyverse" )
if (! require ("BFS" )) install.packages ("BFS" )
if (! require ("giscoR" )) install.packages ("giscoR" )
if (! require ("mapview" )) install.packages ("mapview" )
if (! require ("sf" )) install.packages ("sf" )
if (! require ("leafsync" )) install.packages ("leafsync" )
if (! require ("leaflet.extras2" )) install.packages ("leaflet.extras2" )
library (tidyverse) # data wrangling and viz ecosystem
library (BFS) # Search and Download Data from the Swiss Statistical Office
library (giscoR) # Access Eurostat Mapping API
library (mapview) # Create Interactive Maps easily
library (sf) # mapping with Simple Feature
library (leaflet) # interactive maps
library (leafsync) # plugin for leaflet
crs_LONGLAT <- "+proj=longlat +datum=WGS84 +no_defs"
```
# 데이터
## 지도
```{r}
# switzerland_sf <- gisco_get_nuts(
# country = "Switzerland",
# nuts_level = 3,
# resolution = "01",
# cache = TRUE,
# update_cache = TRUE)
switzerland_sf <- sf:: st_read ("data/gisco-services.ec.europa.eu_distribution_v2_nuts_geojson_NUTS_RG_01M_2016_4326_LEVL_3.geojson" )
switzerland_sf
```
## 스위스 데이터셋
```{r}
# Swiss dataset: https://www.bfs.admin.ch/asset/de/px-x-1502000000_101
swiss_students <- BFS:: bfs_get_data (number_bfs = "px-x-1502000000_101" , language = "de" , clean_names = TRUE )
swiss_students_gender <- swiss_students %>%
pivot_wider (names_from = geschlecht, values_from = lernende) %>%
mutate (share_woman = round (Frau/ ` Geschlecht - Total ` * 100 , 1 ))
swiss_students_gender
```
## 지도와 데이터 결합
```{r}
# Preferably using NUTS-3 code if possible
swiss_student_map <- swiss_students_gender %>%
filter (schulkanton != "Schweiz" ) %>%
mutate (schulkanton = str_remove (schulkanton, ".*/" ),
schulkanton = str_trim (schulkanton),
schulkanton = recode (schulkanton, "Berne" = "Bern" , "Grischun" = "Graubünden" , "Wallis" = "Valais" )) %>%
left_join (switzerland_sf, by = c ("schulkanton" = "NUTS_NAME" ))
swiss_student_map
```
# 시각화
## 교육수준
```{r}
swiss_student_map_bildungsstufe <- swiss_student_map %>%
filter (jahr == "2001/02" ,
schulkanton != "Schweiz" ,
staatsangehorigkeit_kategorie == "Schweiz" ) %>%
select (schulkanton, jahr, bildungsstufe, share_woman, geometry) %>%
pivot_wider (names_from = "bildungsstufe" , values_from = "share_woman" ) %>%
sf:: st_as_sf ()
swiss_student_map_bildungsstufe %>%
mapview (zcol = "Bildungsstufe - Total" , layer.name = "Total education level, % Woman" )
```
## 동기화
```{r}
# Synchronize multiple maps -----------------------------------------------
leafsync:: sync (
swiss_student_map_bildungsstufe %>%
mapview (zcol = "Tertiärstufe" , layer.name = "Tertiary level, % Woman" ),
swiss_student_map_bildungsstufe %>%
mapview (zcol = "Sekundarstufe II" , layer.name = "Secondary level II, % Woman" ),
swiss_student_map_bildungsstufe %>%
mapview (zcol = "Obligatorische Schule" , layer.name = "Mandatory school, % Woman" ),
swiss_student_map_bildungsstufe %>%
mapview (zcol = "Nicht auf Stufen aufteilbare Ausbildungen" , layer.name = "Training that cannot be divided into levels, % Woman" )
)
```
## 슬라이더
:::{.column-page}
```{r}
# Comparing maps with a slider --------------------------------------------
swiss_student_map_bildungsstufe_1999 <- swiss_student_map %>%
filter (jahr == "1999/00" ,
schulkanton != "Schweiz" ,
staatsangehorigkeit_kategorie == "Schweiz" ) %>%
select (schulkanton, jahr, bildungsstufe, share_woman, geometry) %>%
pivot_wider (names_from = "bildungsstufe" , values_from = "share_woman" ) %>%
sf:: st_as_sf ()
map1 <- mapview (swiss_student_map_bildungsstufe, zcol = "Bildungsstufe - Total" )
map2 <- mapview (swiss_student_map_bildungsstufe_1999, zcol = "Bildungsstufe - Total" )
map1 | map2
```
:::
# 한국 데이터
## 지도
```{r}
# korea_sf <- giscoR::gisco_get_nuts(
# resolution = "1",
# epsg = "4326",
# nuts_level = 1,
# cache = TRUE,
# update_cache = TRUE,
# country = "KOR") |>
# sf::st_transform(crsLONGLAT)
library (sf)
library (tidyverse)
korea_sf_raw <- sf:: read_sf ("data/gadm41_KOR_1.json" )
korea_sf <- korea_sf_raw %>%
separate (NL_NAME_1, into = c ("시도명" , "한자" ), sep= "( \\ || \\ ()" ) %>%
select (시도명, geometry)
plot (korea_sf)
```
## 데이터
```{r}
library (krvote)
votes_tbl <- krvote:: election_20220309$ 득표율 %>%
group_by (시도명) %>%
summarise (이재명 = sum (이재명),
윤석열 = sum (윤석열))
votes_tbl
```
## 결합
```{r}
vote_sf <- korea_sf %>%
left_join (votes_tbl) %>%
mutate (득표마진 = 이재명 - 윤석열)
```
# 시각화
## 대선(이재명)
```{r}
library (mapview)
palfunc <- function (n, alpha = 1 , begin = 0 , end = 1 , direction = 1 ) {
colors <- RColorBrewer:: brewer.pal (11 , "RdBu" )
if (direction < 0 ) colors <- rev (colors)
colorRampPalette (colors, alpha = alpha)(n)
}
vote_sf %>%
mapview (zcol = "득표마진" , layer.name = "이재명 - 윤석열" , col.regions = palfunc)
```
## 이재명 vs 윤석열
```{r}
library (mapview)
leafsync:: sync (
vote_sf %>%
mapview (zcol = "이재명" , layer.name = "이재명 득표수" ),
vote_sf %>%
mapview (zcol = "윤석열" , layer.name = "윤석열 득표수" )
)
```
## 대선 비교
:::{.column-page}
```{r}
vote_2012 <- krvote:: election_20121219$ 득표율 %>%
group_by (시도명) %>%
summarise (박근혜 = sum (박근혜),
문재인 = sum (문재인))
vote_2012_sf <- korea_sf %>%
left_join (vote_2012) %>%
mutate (득표마진 = 문재인 - 박근혜)
map_2022 <- mapview (vote_2012_sf, zcol = "득표마진" , layer.name = "이재명 - 윤석열" , col.regions = palfunc)
map_2012 <- mapview (vote_sf, zcol = "득표마진" , layer.name = "문재인 - 박근혜" , col.regions = palfunc)
map_2012 | map_2022
```
:::