> ## 2 데이터 전처리 1 : 지역 정보
>
> # Step 1 : 집계구 만들기
>
> library(sp)
> install.packages("geojsonio")
> library(geojsonio)
> setwd(dirname(rstudioapi::getSourceEditorContext()$path))
> dir.create("./01_save")
> # 행정동 geojson 불러오기
> admin <- geojsonio::geojson_read("./SBJ_1910_001/tl_scco_emd.geojson", what = "sp")
> save(admin, file = "./01_save/01_001_admin.rdata")
> # 플로팅
> plot(admin)
>
> ## 집계구 외곽 경계 만들기
> library(raster)
> library(leaflet)
> # 외곽 경계 만들기 : x_min, x_max, y_min, y_max
> fishnet <- as(raster::extent(126.50625, 127.42245, 36.99653, 37.483419), "SpatialPolygons")
> # WGS84 좌표계 투영
> proj4string(fishnet) <- "+proj=longlat +datum=WGS84 +no_defs _ellps=WGS84 +towgs84=0,0,0"
> # 플로팅
> plot(fishnet, border = "red")
> plot(admin, add=T)
>
> ## fishnet(집계구) 만들기
> # 래스터 변환
> fishnet <- raster(fishnet)
> # 0.1도 단위로 분할
> res(fishnet) <- .01
[1] TRUE TRUE
> # 좌표계 투영
> crs(fishnet) <- CRS("+proj=longlat +datum=WGS84 +no_defs +ellps=WGS84 +towgs84=0,0,0")
> # Polygon으로 변환
> fishnet <- rasterToPolygons(fishnet)
> # 지도 시각화
> leaflet() %>% addTiles() %>%
+ addPolygons(data = fishnet, weight = 0.4, fillOpacity = 0) %>%
+ addPolygons(data = admin, color = "red")
>
> ## 셀별 일련번호 부여하기
> # 현재 번호 없음
> fishnet$id
NULL
> # 일련번호 부여
> fishnet@data <- data.frame(id = 1:nrow(fishnet))
> # 저장
> save(fishnet, file = "./01_save/01_002_fishnet.rdata")
> # 일련번호 확인
> head(fishnet$id, 10)
[1] 1 2 3 4 5 6 7 8 9 10
>
>
> # Step 2 : 정류장-버스노선 매핑 테이블 생성
>
> ## 정류장 정보 불러오기
> # CSV 불러오기
> sta_table <- read.csv("./SBJ_1910_001/stations_table.csv", fileEncoding = "UTF-8")
> # 필요한 컬럼만 추출
> colnames(sta_table)
[1] "표준정류장ID" "시군명" "정류소명" "정류소영문명" "정류소번호" "중앙차로여부"
[7] "관할관청" "위치" "WGS84위도" "WGS84경도" "모바일정류장ID" "이비카드정류장ID"
> keeps <- c("표준정류장ID", "이비카드정류장ID", "WGS84위도", "WGS84경도", "시군명", "정류소명")
> sta_table <- sta_table[keeps]
> # NA 제거
> sta_table <- na.omit(sta_table)
> # 저장
> save(sta_table, file = "./01_save/01_003_sta_table.rdata")
> # 불필요한 변수 지우기
> rm("keeps")
> head(sta_table, 2)
표준정류장ID 이비카드정류장ID WGS84위도 WGS84경도 시군명 정류소명
106 208000192 4103451 37.40163 126.9109 안양시 삼성빌라
158 232000001 4115377 37.59633 126.7213 김포시 유현마을.신동아아파트
>
> ## 버스노선(route)별 정류장 정보 불러오기
> # CSV 불러오기
> route_sta <- read.csv("./SBJ_1910_001/routestationinfo.csv", fileEncoding = "UTF-8")
> # 필요한 컬럼만 추출
> colnames(route_sta)
[1] "seq" "pr_station_id" "bus_line_no" "bus_line_no_seq" "station_nm" "station_id"
[7] "mobile_no"
> keeps <- c("bus_line_no", "bus_line_no_seq", "station_id", "station_nm")
> route_sta <- route_sta[keeps]
> head(route_sta, 2)
bus_line_no bus_line_no_seq station_id station_nm
1 10-4 1 228001552 용인터미널
2 10-4 2 277102443 용인터미널(경유)
>
> ## 매핑 테이블 생성 : 정류장-버스노선
> # 정류장 id(station_id) + 좌표값(위도, 경도) 결합
> route_sta <- merge(route_sta, sta_table, by.x = "station_id", by.y = "표준정류장ID")
> # 결측치 확인
> sum(is.na(route_sta))
[1] 0
> # 저장
> save(route_sta, file = "./01_save/01_004_route_sta.rdata")
> rm("keeps")
> head(route_sta, 2)
station_id bus_line_no bus_line_no_seq station_nm 이비카드정류장ID WGS84위도 WGS84경도 시군명
1 124000437 5 43 미사강변18단지.강일리버10단지 4103229 37.56 127.1818 하남시
2 124000437 3 53 미사강변18단지.강일리버10단지 4103229 37.56 127.1818 하남시
정류소명
1 미사강변18단지.강일리버10단지
2 미사강변18단지.강일리버10단지
>
>
> ## 3 데이터 전처리 2 : 교통 카드 데이터
>
> # Step 1 : 개별 이동 데이터 생성
>
> ## 변수명 한글로 변경
> setwd(dirname(rstudioapi::getSourceEditorContext()$path))
> # 개별 이동 데이터(trip_chain) 불러오기
> trip_chain <- read.csv("./SBJ_1910_001/TripChain.csv", fileEncoding = "UTF-8")
> # 변수명 한글로 변경
> colnames(trip_chain) <- c("암호화카드번호", "트랜잭션ID", "환승횟수", "교통카드발행사ID",
+ "총이용객수", "사용자구분", "교통수단CD1", "교통수단CD2",
+ "교통수단CD3", "교통수단CD4", "교통수단CD5", "버스노선ID1",
+ "버스노선ID2", "버스노선ID3", "버스노선ID4", "버스노선ID5",
+ "차량ID1", "차량ID2", "차량ID3", "차량ID4",
+ "차량ID5", "총통행거리", "총탑승시간", "총소요시간",
+ "승차일시1", "승차일시2", "승차일시3", "승차일시4",
+ "승차일시5", "하차일시1", "하차일시2", "하차일시3",
+ "하차일시4", "하차일시5", "최초승차일시", "최종하차일시",
+ "승차역ID1", "승차역ID2", "승차역ID3", "승차역ID4",
+ "승차역ID5", "하차역ID1", "하차역ID2", "하차역ID3",
+ "하차역ID4", "하차역ID5", "최초승차역ID", "최종하차역ID",
+ "총이용금액", "수집건수", "트립체인완료코드")
> head(trip_chain)
암호화카드번호 트랜잭션ID 환승횟수 교통카드발행사ID 총이용객수 사용자구분 교통수단CD1 교통수단CD2 교통수단CD3
1 900079696430 56 2 9000923 1 1 500 500 NA
2 900079697651 5 1 9000923 1 1 500 NA NA
3 900079698254 32 1 9000923 1 1 500 NA NA
4 900079699257 80 1 9000923 1 1 500 NA NA
5 900079701419 64 1 9000923 1 1 530 NA NA
6 900079701419 65 1 9000923 1 1 530 NA NA
교통수단CD4 교통수단CD5 버스노선ID1 버스노선ID2 버스노선ID3 버스노선ID4 버스노선ID5 차량ID1 차량ID2 차량ID3
1 NA NA 41002045 41002044 NA NA NA 141771735 141771587 NA
2 NA NA 41031040 NA NA NA NA 141701792 NA NA
3 NA NA 41031121 NA NA NA NA 141701843 NA NA
4 NA NA 41031013 NA NA NA NA 141701450 NA NA
5 NA NA 41020001 NA NA NA NA 141703985 NA NA
6 NA NA 41020001 NA NA NA NA 141703953 NA NA
차량ID4 차량ID5 총통행거리 총탑승시간 총소요시간 승차일시1 승차일시2 승차일시3 승차일시4 승차일시5 하차일시1
1 NA NA 11170 25 25 2.01807e+13 2.01807e+13 NA NA NA 2.01807e+13
2 NA NA 1700 3 3 2.01807e+13 NA NA NA NA 2.01807e+13
3 NA NA 23180 66 66 2.01807e+13 NA NA NA NA 2.01807e+13
4 NA NA 500 1 1 2.01807e+13 NA NA NA NA 2.01807e+13
5 NA NA 3240 8 8 2.01807e+13 NA NA NA NA 2.01807e+13
6 NA NA 2940 8 8 2.01807e+13 NA NA NA NA 2.01807e+13
하차일시2 하차일시3 하차일시4 하차일시5 최초승차일시 최종하차일시 승차역ID1 승차역ID2 승차역ID3 승차역ID4
1 2.01807e+13 NA NA NA 2.01807e+13 20180701064826 4116828 4150144 NA NA
2 NA NA NA NA 2.01807e+13 20180701072520 4117280 NA NA NA
3 NA NA NA NA 2.01807e+13 20180701134223 4199619 NA NA NA
4 NA NA NA NA 2.01807e+13 20180701224543 4108130 NA NA NA
5 NA NA NA NA 2.01807e+13 20180701085910 4100122 NA NA NA
6 NA NA NA NA 2.01807e+13 20180701221723 4100098 NA NA NA
승차역ID5 하차역ID1 하차역ID2 하차역ID3 하차역ID4 하차역ID5 최초승차역ID 최종하차역ID 총이용금액 수집건수
1 NA NA NA NA NA NA NA 4116708 1350 2
2 NA NA NA NA NA NA NA 4117269 1250 1
3 NA NA NA NA NA NA NA 4107936 1550 1
4 NA NA NA NA NA NA NA 4116717 1250 1
5 NA NA NA NA NA NA NA 4116848 2050 1
6 NA NA NA NA NA NA NA 4100121 2050 1
트립체인완료코드
1 ;
2 ;
3 ;
4 ;
5 ;
6 ;
>
> ## 이동 시작 일시
> # 옵션 변경(지수 => 숫자)
> options("scipen" = 100)
> head(trip_chain$최초승차일시)
[1] 20180701052543 20180701072156 20180701123653 20180701224424 20180701085058 20180701220922
> # 이동 시작 날짜(start_day) => 1일 ~ 4일 중 하나
> trip_chain$start_day <- as.numeric(substr(trip_chain[, c("최초승차일시")], 7, 8))
> head(trip_chain[, c("최초승차일시", "start_day")])
최초승차일시 start_day
1 20180701052543 1
2 20180701072156 1
3 20180701123653 1
4 20180701224424 1
5 20180701085058 1
6 20180701220922 1
> # 이동 시작 시간(start_hour) => 새벽 4시 ~ 밤 23시 중 하나
> trip_chain$start_hour <- as.numeric(substr(trip_chain[, c("최초승차일시")], 9, 10))
> head(trip_chain[, c("최초승차일시", "start_hour")])
최초승차일시 start_hour
1 20180701052543 5
2 20180701072156 7
3 20180701123653 12
4 20180701224424 22
5 20180701085058 8
6 20180701220922 22
>
> ## 이동 종료 일시
> head(trip_chain$최종하차일시)
[1] "20180701064826 " "20180701072520 " "20180701134223 " "20180701224543 " "20180701085910 " "20180701221723 "
> # 이동 시작 날짜(end_day) => 1일 ~ 4일 중 하나
> trip_chain$end_day <- as.numeric(substr(trip_chain[, c("최종하차일시")], 7, 8))
> head(trip_chain[, c("최종하차일시", "end_day")])
최종하차일시 end_day
1 20180701064826 1
2 20180701072520 1
3 20180701134223 1
4 20180701224543 1
5 20180701085910 1
6 20180701221723 1
> # 이동 시작 시간(end_hour) => 새벽 4시 ~ 밤 23시 중 하나
> trip_chain$end_hour <- as.numeric(substr(trip_chain[, c("최종하차일시")], 9, 10))
> head(trip_chain[, c("최종하차일시", "end_hour")])
최종하차일시 end_hour
1 20180701064826 6
2 20180701072520 7
3 20180701134223 13
4 20180701224543 22
5 20180701085910 8
6 20180701221723 22
>
> head(trip_chain[, c("최초승차일시", "start_day", "start_hour", "최종하차일시", "end_day", "end_hour")])
최초승차일시 start_day start_hour 최종하차일시 end_day end_hour
1 20180701052543 1 5 20180701064826 1 6
2 20180701072156 1 7 20180701072520 1 7
3 20180701123653 1 12 20180701134223 1 13
4 20180701224424 1 22 20180701224543 1 22
5 20180701085058 1 8 20180701085910 1 8
6 20180701220922 1 22 20180701221723 1 22
> # 저장
> save(trip_chain, file = "./01_save/02_001_trip_chain_full.rdata")
>
>
> # Step 2 : 개별 이동 + 정류장 정보 매핑
>
> ## 출발-도착 정류장 정보에 좌표값 결합
> library(dplyr)
> load("./01_save/01_003_sta_table.rdata")
> # 버스 정류장 정보(sta_table) 컬럼 이름 변경
> colnames(sta_table) <- c("표준정류장ID", "이비카드정류장ID", "S_WGS84위도", "S_WGS84경도", "S_시군명", "S_정류소명")
> # 출발점 기준 => 이비카드정류당ID + 승차역ID1 결합
> trip_chain <- merge(trip_chain, sta_table, by.x = "승차역ID1", by.y = "이비카드정류장ID")
> # 결측치 확인
> sum(is.na(trip_chain$S_정류소명))
[1] 0
> # 버스 정류장 정보(sta_table) 컬럼 이름 변경
> colnames(sta_table) <- c("표준정류장ID", "이비카드정류장ID", "E_WGS84위도", "E_WGS84경도", "E_시군명", "E_정류소명")
> # 도착점 기준 => 이비카드정류당ID + 최종하차역ID 결합
> trip_chain <- merge(trip_chain, sta_table, by.x = "최종하차역ID", by.y = "이비카드정류장ID")
> # 결측치 확인
> sum(is.na(trip_chain$E_정류소명))
[1] 0
> # 저장
> save(trip_chain, file = "./01_save/02_002_trip_chain_full.rdata")
>
> ## 승하차가 많은 지역은 어디인가?
> # 피벗 테이블 만들기
> trip_chain_pivot <- as.matrix(table(trip_chain$S_시군명, trip_chain$E_시군명))
> trip_chain_pivot
가평시 고양시 과천시 광명시 광주시 구리시 군포시 김포시 남양주시 동두천시 부천시 성남시 수원시 시흥시 안산시
가평시 0 0 0 0 0 0 0 0 0 0 0 0 6 0 0
고양시 0 0 0 0 0 0 0 0 0 0 0 4 72 0 0
과천시 0 0 0 0 0 0 0 0 0 0 0 5 78 0 0
광명시 0 0 0 3 0 0 9 0 0 0 0 1 228 0 0
광주시 0 0 0 0 13 0 0 0 0 0 0 517 167 0 0
...
> # 어느 지역에서 가장 많이 승차하였는가?
> sort(colSums(trip_chain_pivot), decreasing = T)
수원시 화성시 용인시 오산시 성남시 안양시 의왕시 안산시 평택시 군포시 광주시 광명시 시흥시
413067 146978 53494 53252 40199 13821 4764 4232 2246 1757 859 502 363
부천시 안성시 고양시 남양주시 과천시 구리시 하남시 김포시 의정부시 파주시 이천시 양주시 여주시
327 197 167 100 89 85 85 72 69 45 43 22 16
가평시 양평군 포천시 동두천시 연천군
8 4 4 3 3
> # 어느 지역에서 가장 많이 하차하였는가?
> sort(rowSums(trip_chain_pivot), decreasing = T)
수원시 화성시 용인시 오산시 성남시 안양시 의왕시 안산시 평택시 군포시 광주시 광명시 시흥시
417521 142403 54215 52650 39624 13798 4913 4259 2560 1676 894 531 354
부천시 안성시 고양시 남양주시 구리시 과천시 의정부시 하남시 김포시 파주시 이천시 양주시 여주시
348 198 153 142 132 122 99 96 67 36 30 27 10
가평시 포천시 양평군 연천군 동두천시
6 4 2 2 1
>
>
> # Step 3 : 분석의 공간적 범위 결정 - 승하차가 가장 많은 지역
>
> ## 데이터 필터링
> # 출발 또는 도착지가 화성시인 경우만 필터링
> trip_chain <- trip_chain %>%
+ filter(S_시군명 == "화성시" | E_시군명 == "화성시")
> # 저장
> save(trip_chain, file = "./01_save/02_003_trip_chain.rdata")
>
> ## OD 행렬 생성
> trip_chain_pivot <- as.matrix(table(trip_chain$S_시군명, trip_chain$E_시군명))
> OD <- as.data.frame(trip_chain_pivot)
> # 통행 발생 순서대로 정렬
> OD <- OD %>%
+ arrange(desc(Freq))
> # 일련번호 재정렬
> rownames(OD) <- 1:nrow(OD)
> head(OD)
Var1 Var2 Freq
1 화성시 화성시 82556
2 수원시 화성시 45200
3 화성시 수원시 40940
4 오산시 화성시 10762
5 화성시 오산시 10577
6 화성시 용인시 4250
>
> ## 지역별 OD 발생량 누적 비율 보기
> # 누적 비율 보기
> OD <- OD %>%
+ mutate(cum = round((cumsum(Freq)/sum(Freq)) * 100, 1))
> # 컬럼명 변경
> colnames(OD) <- c("From", "To", "Freq", "Cum")
> head(OD)
From To Freq Cum
1 화성시 화성시 82556 39.9
2 수원시 화성시 45200 61.8
3 화성시 수원시 40940 81.6
4 오산시 화성시 10762 86.8
5 화성시 오산시 10577 91.9
6 화성시 용인시 4250 93.9
> # OD 매트릭스 저장
> save(OD, file = "./01_save/02_003_OD.rdata")
>
> ## 통행량 집중도 확인 : 지니계수와 로렌츠 곡선
> install.packages("ineq")
> library(ineq)
> # 지니계수
> ineq(OD$Freq, type = "Gini")
[1] 0.9941338
> # 로렌츠 곡선 그리기
> plot(OD$Freq, col = "red", type = "l", lwd = 2)
>
> ## 대상 지역 교통량 데이터만 추출
> # 출발 또는 도착 지역 지정
> patterns <- c("수원시", "화성시", "용인시", "오산시")
> # 필요 변수 지정
> colnames(sta_table) <- c("표준정류장ID", "이비카드정류장ID", "WGS84위도", "WGS84경도", "시군명", "정류소명")
> # 필요한 지역만 필터링
> sta_table <- filter(sta_table, grepl(paste(patterns, collapse = "|"), 시군명))
> # 일련번호 다시 부여
> rownames(sta_table) <- 1:nrow(sta_table)
> # 필터링 결과 확인
> unique(sta_table$시군명)
[1] "화성시" "용인시" "수원시" "오산시"
> # 저장
> save(sta_table, file = "./01_save/02_003_sta_table.rdata")
출처 : 김철민, ⌜공공데이터로 배우는 R 데이터분석 with 샤이니⌟, 이지스퍼블리싱, 2022
'데이터분석 > R' 카테고리의 다른 글
[R 데이터분석 with 샤이니] 교통 카드 데이터 분석 사례 03 - 교통 흐름 분석 (0) | 2022.08.04 |
---|---|
[R 데이터분석 with 샤이니] 교통 카드 데이터 분석 사례 02 - 기초 분석 (0) | 2022.07.30 |
[R 데이터분석 with 샤이니] 커피 전문점 접근성 분석 (Shiny) (0) | 2022.07.28 |
[R 데이터분석 with 샤이니] 지진 발생 분석 (Shiny) (0) | 2022.07.26 |
[R 데이터분석 with 샤이니] 여러 지역 아파트가격 상관관계 비교 (Shiny) (0) | 2022.07.26 |