public bigdata

[데이터분석] 교통사고데이터 시각화 본문

데이터분석

[데이터분석] 교통사고데이터 시각화

public bigdata 2018. 5. 6. 00:29
car_visualization.R
# data import ====
car=read.csv("caracci.csv")
head(car)
# 데이터는 아래와 같다.
##   year       ymdh mm ampm day dead toinjure heavyinjured rightinjured
## 1 2016 2016122320 35 야간  금    1        1            0            0
## 2 2016 2016122517 48 주간  일    1        1            0            0
## 3 2016 2016122519  5 야간  일    1        1            0            0
## 4 2016 2016122610 40 주간  월    1        1            0            0
## 5 2016 2016122819 40 야간  수    1        1            0            0
## 6 2016 2016111207 34 주간  토    1        1            0            0
##   local1 local2 accitype roadtype  cartype longitude latitude
## 1   경기 광주시 차대사람   교차로   승용차  127.2936 37.38769
## 2   서울 금천구 차대사람   단일로   승용차  126.8891 37.47878
## 3   충북 진천군 차대사람   단일로   화물차  127.4316 36.91593
## 4   경북 경주시 차대사람   단일로   승합차  129.2822 35.74239
## 5   경남 진주시 차대사람   단일로   승용차  128.1180 35.17351
## 6   경남 거제시 차대사람   단일로 건설기계  128.6200 34.88566
str(car)
## 'data.frame':    4119 obs. of  16 variables:
##  $ year        : int  2016 2016 2016 2016 2016 2016 2016 2016 2016 2016 ...
##  $ ymdh        : int  2016122320 2016122517 2016122519 2016122610 2016122819 2016111207 2016110919 2016111005 2016110711 2016110818 ...
##  $ mm          : int  35 48 5 40 40 34 25 0 5 0 ...
##  $ ampm        : Factor w/ 2 levels "야간","주간": 1 2 1 2 1 2 1 1 2 1 ...
##  $ day         : Factor w/ 7 levels "금","목","수",..: 1 5 5 4 3 6 3 2 4 7 ...
##  $ dead        : int  1 1 1 1 1 1 1 1 1 1 ...
##  $ toinjure    : int  1 1 1 1 1 1 1 1 1 1 ...
##  $ heavyinjured: int  0 0 0 0 0 0 0 0 0 0 ...
##  $ rightinjured: int  0 0 0 0 0 0 0 0 0 0 ...
##  $ local1      : Factor w/ 17 levels "강원","경기",..: 2 9 17 4 3 3 2 12 16 13 ...
##  $ local2      : Factor w/ 205 levels "가평군","강남구",..: 26 38 172 12 171 9 190 86 132 103 ...
##  $ accitype    : Factor w/ 3 levels "차대사람","차대차",..: 1 1 1 1 1 1 1 1 3 1 ...
##  $ roadtype    : Factor w/ 5 levels "고가도로위","교차로",..: 2 4 4 4 4 4 4 4 4 4 ...
##  $ cartype     : Factor w/ 10 levels "건설기계","농기계",..: 4 4 10 5 4 1 4 4 1 4 ...
##  $ longitude   : num  127 127 127 129 128 ...
##  $ latitude    : num  37.4 37.5 36.9 35.7 35.2 ...
car=car[,-1] # 연도는 모두 2016년 이므로 연도변수 제거.
car$m=substr(car$ymdh,5,6) # 날짜변수에서 월만 추출하여 변수 생성.

# 범주형변수여야 하는 것들 범주형으로 변경.
car$ymdh=as.factor(car$ymdh)
car$mm=as.factor(car$mm)
car$m=as.factor(car$m)
car$day<- factor(car$day, levels = c("월","화","수","목","금","토","일"))
# library ====
library(ggplot2)
library(plyr)
library(plotly)
library(leaflet)
# 기본기술통계 ====
str(car)
## 'data.frame':    4119 obs. of  16 variables:
##  $ ymdh        : Factor w/ 3234 levels "2016010103","2016010104",..: 3149 3166 3167 3172 3193 2759 2736 2739 2708 2724 ...
##  $ mm          : Factor w/ 60 levels "0","1","2","3",..: 36 49 6 41 41 35 26 1 6 1 ...
##  $ ampm        : Factor w/ 2 levels "야간","주간": 1 2 1 2 1 2 1 1 2 1 ...
##  $ day         : Factor w/ 7 levels "월","화","수",..: 5 7 7 1 3 6 3 4 1 2 ...
##  $ dead        : int  1 1 1 1 1 1 1 1 1 1 ...
##  $ toinjure    : int  1 1 1 1 1 1 1 1 1 1 ...
##  $ heavyinjured: int  0 0 0 0 0 0 0 0 0 0 ...
##  $ rightinjured: int  0 0 0 0 0 0 0 0 0 0 ...
##  $ local1      : Factor w/ 17 levels "강원","경기",..: 2 9 17 4 3 3 2 12 16 13 ...
##  $ local2      : Factor w/ 205 levels "가평군","강남구",..: 26 38 172 12 171 9 190 86 132 103 ...
##  $ accitype    : Factor w/ 3 levels "차대사람","차대차",..: 1 1 1 1 1 1 1 1 3 1 ...
##  $ roadtype    : Factor w/ 5 levels "고가도로위","교차로",..: 2 4 4 4 4 4 4 4 4 4 ...
##  $ cartype     : Factor w/ 10 levels "건설기계","농기계",..: 4 4 10 5 4 1 4 4 1 4 ...
##  $ longitude   : num  127 127 127 129 128 ...
##  $ latitude    : num  37.4 37.5 36.9 35.7 35.2 ...
##  $ m           : Factor w/ 12 levels "01","02","03",..: 12 12 12 12 12 11 11 11 11 11 ...
summary(car)

## 데이터의 특성은 아래와 같다.

##          ymdh            mm         ampm      day           dead       
##  2016122118:   6   0      : 396   야간:2072   월:584   Min.   : 1.000  
##  2016091309:   5   30     : 322   주간:2047   화:560   1st Qu.: 1.000  
##  2016102518:   5   50     : 305               수:565   Median : 1.000  
##  2016103106:   5   40     : 304               목:596   Mean   : 1.042  
##  2016011606:   4   10     : 292               금:666   3rd Qu.: 1.000  
##  2016011721:   4   20     : 288               토:635   Max.   :10.000  
##  (Other)   :4090   (Other):2212               일:513                   
##     toinjure       heavyinjured     rightinjured         local1    
##  Min.   : 1.000   Min.   : 0.000   Min.   : 0.0000   경기   : 749  
##  1st Qu.: 1.000   1st Qu.: 0.000   1st Qu.: 0.0000   경북   : 477  
##  Median : 1.000   Median : 0.000   Median : 0.0000   충남   : 372  
##  Mean   : 1.576   Mean   : 0.252   Mean   : 0.2595   경남   : 359  
##  3rd Qu.: 1.000   3rd Qu.: 0.000   3rd Qu.: 0.0000   서울   : 342  
##  Max.   :67.000   Max.   :22.000   Max.   :62.0000   전남   : 327  
##                                                      (Other):1493  
##           local2         accitype          roadtype   
##  서구        :  78   차대사람:1647   고가도로위:  14  
##  남구        :  76   차대차  :1646   교차로    :1285  
##  창원시(통합):  75   차량단독: 826   기타/불명 : 103  
##  청주시      :  74                   단일로    :2704  
##  북구        :  69                   지하도로내:  13  
##  동구        :  58                                    
##  (Other)     :3689                                    
##              cartype       longitude        latitude           m       
##  승용차          :2023   Min.   :118.0   Min.   :19.69   10     : 410  
##  화물차          : 914   1st Qu.:126.9   1st Qu.:35.52   12     : 400  
##  이륜차          : 415   Median :127.2   Median :36.41   11     : 396  
##  승합차          : 261   Mean   :127.6   Mean   :36.36   09     : 353  
##  원동기장치자전거: 184   3rd Qu.:128.4   3rd Qu.:37.37   04     : 346  
##  자전거          : 113   Max.   :130.9   Max.   :38.48   07     : 341  
##  (Other)         : 209                                   (Other):1873
sum(car$dead)
## [1] 4292
# 사망자수 별 교통사고 빈도.====
car_dead=ddply(car,.(dead), function(sub) {
  data.frame(dead_count=nrow(sub))})
car_dead$dead_count =car_dead$dead_count +10
ggplot(data=car_dead,aes(x=as.factor(dead),y=dead_count,fill=as.factor(dead)))+geom_bar(stat = "identity")+
  geom_text(aes(label=dead_count-10),color="red",size=10)
## 사망사고 데이터는 주로 1명의 사망자가 발생한 경우가 압도적이므로 아래에 나오는 단어 "사망사고"와 "사망명수"는 같은 의미이다.

# ggplot2 visualization====
# 
# 2 월별 교통사고 건수 및 사망자수
# 3 am/pm별 교통사고 사망자수 

ggplot(data=ddply(car,.(ampm),summarize,dead_byampm=sum(dead)),
       aes(x=as.factor(ampm),y=dead_byampm,
           fill=as.factor(ampm)))+geom_bar(stat = "identity")+
  geom_text(aes(label=dead_byampm),color="red",size=10)

# 3 am/pm별 교통사고 건수.
ggplot(data=ddply(car,.(ampm), function(sub) {
  data.frame(acci_count=nrow(sub))}),
  aes(x=as.factor(ampm),y=acci_count,
      fill=as.factor(ampm)))+
  geom_bar(stat = "identity")+
  geom_text(aes(label=acci_count),color="red",size=10)

# 4 요일별 교통사고 사망자수====
ggplot(data=ddply(car,.(day),summarize,dead_byday=sum(dead)),
       aes(x=as.factor(day),y=dead_byday,
           fill=as.factor(day)))+geom_bar(stat = "identity")+
  geom_text(aes(label=dead_byday),color="red",size=10)

# 4 요일별 교통사고 건수.
ggplot(data=ddply(car,.(day), function(sub) {
  data.frame(acci_count=nrow(sub))}),
  aes(x=as.factor(day),y=acci_count,
      fill=as.factor(day)))+
  geom_bar(stat = "identity")+
  geom_text(aes(label=acci_count),color="red",size=10)

# 5 교통사고 유형별 사망자수.====
ggplot(data=ddply(car,.(accitype),summarize,dead_byaccitype=sum(dead)),
       aes(x=as.factor(accitype),y=dead_byaccitype,
           fill=as.factor(accitype)))+geom_bar(stat = "identity")+
  geom_text(aes(label=dead_byaccitype),color="red",size=10)

# 5 교통사고 유형별 교통사고 건수.
ggplot(data=ddply(car,.(accitype), function(sub) {
  data.frame(acci_count=nrow(sub))}),
  aes(x=as.factor(accitype),y=acci_count,
      fill=as.factor(accitype)))+
  geom_bar(stat = "identity")+
  geom_text(aes(label=acci_count),color="red",size=10)

# 6 roadtype 사망건수.====
ggplot(data=ddply(car,.(roadtype), function(sub) {
  data.frame(acci_count=nrow(sub))}),
  aes(x=as.factor(roadtype),y=acci_count,
      fill=as.factor(roadtype)))+
  geom_bar(stat = "identity")+ geom_text(aes(label=acci_count),color="red",size=10)

# 7 cartype 사망건수.====
ggplot(data=ddply(car,.(cartype), function(sub) {
  data.frame(acci_count=nrow(sub))}),
  aes(x=as.factor(cartype),y=acci_count,
      fill=as.factor(cartype)))+
  geom_bar(stat = "identity")+
  geom_text(aes(label=acci_count),color="red",size=10)

# 8 월별 사망건수.====
ggplot(data=ddply(car,.(m), function(sub) {
  data.frame(acci_count=nrow(sub))}),
  aes(x=as.factor(m),y=acci_count,
      fill=as.factor(m)))+
  geom_bar(stat = "identity")+
  geom_text(aes(label=acci_count),color="red",size=5)

# 9 
g <- ggplot(car, aes(cartype))
g + geom_bar(aes(fill=accitype), width = 0.5,position = "fill") + 
  theme(axis.text.x = element_text(angle=65, vjust=0.6)) +
  labs(title="Categorywise Bar Chart", 
       subtitle="Manufacturer of vehicles", 
       caption="Source: Manufacturers from 'mpg' dataset")

# 10 월별 교통사고 수.
data1=ddply(car,.(m,cartype), function(sub) {
  data.frame(acci_count=nrow(sub))})
ggplot=ggplot(data=data1,aes(x=m,y=acci_count,colour=cartype,group=cartype)) +
  geom_line(size=3)
ggplot+scale_color_brewer(palette = "Paired")

# leaflet mapping ====
# 교통사고 발생 위치별로 plot 
#https://plot.ly/r/choropleth-maps/#choropleth-maps-in-r
# 밑에 꺼랑 그냥 점 찍고 거기에 사망건수 별로 색깔 주기. 
# 예를들어 지역별 교통사고 건수, 사망자수, 그리고 건수 대비 사망자수.
# 
# pal <- colorFactor("Set1",  car$ampm)
# 
# 
# leaflet(data=car) %>%
#   # base map
#   addTiles() %>%
#   addCircles(lng = ~longitude,lat=~latitude,
#              popup = ~as.factor(dead),
#              color = ~pal(ampm)) %>% addMarkers(
#                clusterOptions = markerClusterOptions()
#              )

## 위의 반응형 그래프는 좌표를 지도에 매핑한 것으로 사망사고가 발생한 교통사고건수이다.