출처 : http://lumiamitie.github.io/r_tutorial/blog_link/leaflet_in_r.html

leaflet은 인터랙티브한 지도를 구현할 수 있게 해주는 오픈소스 자바스크립트 라이브러리이다

R의 leaflet 패키지는 R에서 데이터를 가지고 쉽게 Leaflet 지도를 생성할 수 있게 해준다

install.packages(‘leaflet’)를 통해 해당 패키지를 설치하면 바로 사용할 수 있다

1. 사망교통사고 2017 _ 사고유형대분류

실습을 위한 데이터는 공공데이터포털의 도로교통공단_전국사망교통사고_2017 데이터 중에서 춘천시의 사고유형 대분류가 차대사람,차대차,차량단독인 경우로만 필터링해서 사용했다

# install.packages('leaflet')
library(leaflet)
## Warning: package 'leaflet' was built under R version 3.6.1
library(dplyr)
## Warning: package 'dplyr' was built under R version 3.6.1
## 
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
library(RColorBrewer)
car_data = read.csv('도로교통공단_전국사망교통사고_2017.csv', stringsAsFactors = FALSE)

사고유형대분류 Creating default map

leaflet(car_data) %>% 
  setView(lng =127.750982, lat = 37.856397, zoom = 12) %>% 
  addTiles() %>% 
  addCircles(lng = ~`경도`, lat=~`위도`)

leaflet(data)를 통해 leaflet map widget을 생성하고 데이터를 연결한다

setView()함수를 사용하면 지도의 중심과 확대 정도를 설정한다

addTiles() 함수는 기본 타일(OpenStreetMap)을 불러와서 지도를 보여준다

addCircles() 함수를 통해 데이터를 원의 형태로 지도에 나타낼 수 있다

각각의 함수는 %>%를 통해 연결할 수 있다

사고유형대분류 Third Party Tiles

leaflet(car_data) %>% 
  setView(lng =127.750982, lat = 37.856397, zoom = 12) %>% 
  addProviderTiles('Stamen.Toner') %>% 
  addCircles(lng = ~`경도`, lat=~`위도`)

addTiles()대신에 addProviderTiles()를 이용하면 OSM이 아닌 다른 형태의 지도를 사용할 수 있다

Stamen.Toner,Stamen.Watercolor, Acetate.terrain, CartoDB.Positron 등의 옵션을 사용할 수 있고

에서 다른 provider들의 지도를 불러올 수 있는 방법에 대해서 알아볼 수 있다

?addProviderTiles
## starting httpd help server ... done

Provider에 제공된 preview 지도를 확인해보자

leaflet(car_data) %>% 
  setView(lng =127.750982, lat = 37.856397, zoom = 12) %>% 
  addProviderTiles('OpenTopoMap') %>% 
  addCircles(lng = ~`경도`, lat=~`위도`,color="red")

사고유형대분류 Color

leaftlet에서는 colorNumeric, colorBin, colorQuantile, colorFactor 등의 함수를 이용해서 색상을 지정하는 함수를 생성할 수 있다.

위에서 사용한 와이파이 정보를 통신사별로 구별하기 위해서 서로 다른 색상을 지정해보려고 한다

colorFactor함수를 이용하면 RColorBrewer 패키지의 색상이나 다른 함수의 색상을 가져와서 구성할 수 있다

첫 번째 인수로는 RColorBrewer의 팔레트 이름, 두 번째 인수는 적용할 데이터(열까지)를 지정한다

car_color = colorFactor('Set1',car_data$`사고유형_대분류`)

색상 함수를 생성하면 color옵션에서 해당 변수에 함수를 사용한 형태로 값을 지정한다

leaflet(car_data) %>% 
  setView(lng =127.750982, lat = 37.856397, zoom = 12) %>% 
  addProviderTiles('Stamen.Toner') %>% 
  addCircles(lng = ~`경도`, lat=~`위도`, popup = ~`사고유형_대분류`, color = ~car_color(`사고유형_대분류`))

사고유형대분류 Legends

leaflet(car_data) %>% 
  setView(lng =127.750982, lat = 37.856397, zoom = 12) %>% 
  addProviderTiles('Stamen.Toner') %>% 
  addCircles(lng = ~`경도`, lat=~`위도`, popup = ~`사고유형_대분류`, color = ~car_color(`사고유형_대분류`)) %>% 
  addLegend(position = 'bottomright', 
            title = 'Wifi Provider', 
            pal = car_color, values = ~`사고유형_대분류`, opacity = 1)

addLegend함수를 이용해서 범례를 추가할 수 있다

position 항목에는 topright“, bottomright, bottomleft, topleft 중 하나를 선택하여 범례의 위치를 지정할 수 있다

pal 옵션에는 우리가 사용했던 색상 팔레트 함수를 입력한다

values 옵션에는 색상 팔레트 함수가 색상을 생성하는데 사용한 변수값을 지정한다

사고유형대분류 Interactive Layer

leaflet() %>% 
  setView(lng =127.750982, lat = 37.856397, zoom = 12) %>% 
  addProviderTiles('Stamen.Toner') %>% 
  addCircles(data = car_data %>% filter(`사고유형_대분류` == '차대사람'), 
             lng = ~경도, lat=~위도, popup = ~`사고유형_대분류`, group = '차대사람', 
             color = ~car_color(`사고유형_대분류`)) %>% 
  addCircles(data = car_data %>% filter(`사고유형_대분류` == '차대차'), 
             lng = ~경도, lat=~위도, popup = ~`사고유형_대분류`, group = '차대차', 
             color = ~car_color(`사고유형_대분류`)) %>% 
  addCircles(data = car_data %>% filter(`사고유형_대분류` == '차량단독'), 
             lng = ~경도, lat=~위도, popup = ~`사고유형_대분류`, group = '차량단독', 
             color = ~car_color(`사고유형_대분류`)) %>% 
  addLayersControl(overlayGroups = c('차대사람', '차대차', '차량단독'),
                   options = layersControlOptions(collapsed = FALSE))
  • 2017년 춘천시 교통사고 사고유형대분류 시각화를 통해 ‘차대사람’, ‘차대차’, ‘차량단독’ 순으로 빈번했다.

  • ’차대차’의 사고 발생 위치를 보면 도심 중심부에 밀집되어 있다.

2. 사망교통사고 2017 _ 주야,요일

실습을 위한 데이터는 공공데이터포털의 도로교통공단_전국사망교통사고_2017 데이터 중에서 춘천시의 주야, 요일 경우로만 필터링해서 사용했다

주야,요일 Creating default map

leaflet(car_data) %>% 
  setView(lng =127.750982, lat = 37.856397, zoom = 12) %>% 
  addTiles() %>% 
  addCircles(lng = ~`경도`, lat=~`위도`)

주야,요일 Third Party Tiles

leaflet(car_data) %>% 
  setView(lng =127.750982, lat = 37.856397, zoom = 12) %>% 
  addProviderTiles('Stamen.Toner') %>% 
  addCircles(lng = ~`경도`, lat=~`위도`)

주야,요일 Color

car_color = colorFactor('Set1',car_data$`주야`)

주야,요일 Legends

leaflet(car_data) %>% 
  setView(lng =127.750982, lat = 37.856397, zoom = 12) %>% 
  addProviderTiles('Stamen.Toner') %>% 
  addCircles(lng = ~`경도`, lat=~`위도`, popup = ~`주야`, color = ~car_color(`주야`)) %>% 
  addLegend(position = 'bottomright', 
            title = 'Wifi Provider', 
            pal = car_color, values = ~`주야`, opacity = 1)

주야,요일 Interactive Layer

leaflet() %>% 
  setView(lng =127.750982, lat = 37.856397, zoom = 12) %>% 
  addProviderTiles('Stamen.Toner') %>% 
  addCircles(data = car_data %>% filter(`주야` == '주간'), 
             lng = ~경도, lat=~위도, popup = ~`주야`, group = '주간', 
             color = ~car_color(`주야`)) %>% 
  addCircles(data = car_data %>% filter(`주야` == '야간'), 
             lng = ~경도, lat=~위도, popup = ~`주야`, group = '야간', 
             color = ~car_color(`주야`)) %>% 
  addLayersControl(overlayGroups = c('주간', '야간'),
                   options = layersControlOptions(collapsed = FALSE))
  • 2017년 춘천시 교통사고 발생 시간은 주간보다 ’야간’에 많이 발생하였다.

  • 도심이 아닌 외곽에서 교통사고는 비교적 ’주간’에 많이 발생하였다.

3.도로형태_대분류

도로형태_대분류 Interactive Layer

car_color = colorFactor('Set1',car_data$`도로형태_대분류`)
leaflet() %>% 
  setView(lng =127.750982, lat = 37.856397, zoom = 12) %>% 
  addProviderTiles('Stamen.Toner') %>% 
  addCircles(data = car_data %>% filter(`도로형태_대분류` == '단일로'), 
             lng = ~경도, lat=~위도, popup = ~`주야`, group = '단일로', 
             color = ~car_color(`도로형태_대분류`)) %>% 
  addCircles(data = car_data %>% filter(`도로형태_대분류` == '교차로'), 
             lng = ~경도, lat=~위도, popup = ~`도로형태_대분류`, group = '교차로', 
             color = ~car_color(`도로형태_대분류`)) %>% 
  addCircles(data = car_data %>% filter(`도로형태_대분류` == '기타'), 
             lng = ~경도, lat=~위도, popup = ~`도로형태_대분류`, group = '기타', 
             color = ~car_color(`도로형태_대분류`)) %>% 
  addLayersControl(overlayGroups = c('단일로','교차로','기타'),
                   options = layersControlOptions(collapsed = FALSE))
  • 2017년 춘천시 교통사고 발생 도로형태는 ’교차로’보다 ’단일로’에서 매우 많이 발생하였다.

  • ’교차로’에서 발생하는 위치가 모여 있어 주의 할 필요하 있다.

4.사상자수

사상자수 Interactive Layer

car_color = colorFactor('Set1',car_data$`사상자수`)
leaflet() %>% 
  setView(lng =127.750982, lat = 37.856397, zoom = 12) %>% 
  addProviderTiles('Stamen.Toner') %>% 
  addCircles(data = car_data %>% filter(`사상자수` == '1'), 
             lng = ~경도, lat=~위도, popup = ~`사상자수`, group = '1', 
             color = ~car_color(`사상자수`)) %>% 
  addCircles(data = car_data %>% filter(`사상자수` == '2'), 
             lng = ~경도, lat=~위도, popup = ~`사상자수`, group = '2', 
             color = ~car_color(`사상자수`)) %>% 
  addCircles(data = car_data %>% filter(`사상자수` == '3'), 
             lng = ~경도, lat=~위도, popup = ~`사상자수`, group = '3', 
             color = ~car_color(`사상자수`)) %>% 
  addCircles(data = car_data %>% filter(`사상자수` == '8'), 
             lng = ~경도, lat=~위도, popup = ~`사상자수`, group = '8', 
             color = ~car_color(`사상자수`)) %>% 
  addLayersControl(overlayGroups = c('1','2','3','8'),
                   options = layersControlOptions(collapsed = FALSE))
  • 2017년 춘천시 사상자수는 ’1명’이 빈번하였고 ’2명’도 간간이 발생하였다..

  • 사상자수가 ’3명’인 사건은 도심이 아닌 고속도로, 외곽에서 발생하였다.