데이터셋 및 함수구성 단계 설명

1. 데이터셋 구성방법

1.1 지하철 역정보 데이터 취득

1.2 순서화된 지하철 리스트 구성


Subway Line Picture

\vspace{0.5cm}

이러한 과정을 통하여 최종적으로 21개의 노선을 갖춘 subwayline이라는 명칭의 List셋을 구성하였다.

2. subway_shortestpath 함수구성방법

환승 구분 | 함수명 | ------------ | ----------------------- | 0번 | subway_shortestpath_0 | 1번 | subway_shortestpath_1 | 2번 | subway_shortestpath_2 |

우선적으로 subway_shortestpath 함수를 구성하는데 있어서 위 3가지 경우를 고려하였다.

2.0 기본 고려사항 및 함수정의

\vspace{0.5cm}

2.1 이동거리(소요시간) 기준 최단거리 함수 설명

\vspace{0.5cm}

위에서 얻어진 각 3가지 경우에 대하여 총 Total이라는 List에 할당한 후 총 Time값이 최소값을 가지는 경우에 대한 경로를 표현한다.

최종적으로 이 3가지를 비교하여 최소값을 가지는 하나의 경로를 선택하여 이를 표현한다.

0. 필요패키지 및 데이터 불러들이기

load('subway_shortestpath_Time.RData') # 추후 패키지 대체
# 내장함수 : subway_pathplot, subway_shortestpath, subway_shortestpath_0, 
#            subway_shortestpath_1, subway_shortestpath_2, geo_pathinfo
# 내장데이터 : dataset, subwayline, transfer_info)
# install.packages("data.table")
load('subin.RData') # 추후 패키지 대체
library(dplyr)
library(data.table)
library(stringr)
library(geosphere)
library(tidyr)
library(ggplot2)
library(ggmap)
library(jpeg)
library(png)
library(httr)
library(jsonlite)
naver_key <- "idSJzfmV9d3DIGBZ5DFL"
Secret <-"PMo3_y6D1C"
kakao_key <- "4febb0939357ec9fee82262801d5314b"

1. 데이터셋 구성단계

1.1 데이터셋 구성

colnames(dataset) <- c("Code", "Name", "Line", "ExCode", "CyCode", 
        "X", "Y", "lat", "long")
#dataset <- dataset[-which(dataset$전철역명%in%c('탕정', '풍기', '마전(무정차)')),]

#geocode_keyword_kakao 함수 이용

query <- c("여주역", "지평역", "북한산우이역", "솔밭공원역", "419민주묘지역", "가오리역", "화계역", "삼양역", "삼양사거리역", "솔샘역", "북한산보국문역", "정릉역" )
query_replace <- str_remove(query, "역")
Result <- data.table("lat"=rep(0,12), "long"=rep(0,12))
for(i in seq_along(query)){
Result[i,] <- geocode_keyword_kakao(query[i], kakao_key =kakao_key)[1,c("lat", "lon")]
dataset[Name==query_replace[i],c("lat","long")] <- Result[i,]
}

key_list <- list()
sub_line <- unique(dataset$호선)
# str_sort() option's default setting - numeric / alpahbet
sub_line <- str_sort(sub_line)

# key_list set : 순서 정리 및 환승노선 변수 추가 전 라인별 지하철
# 리스트
for (i in seq_along(sub_line)) {
    key_list[[i]] <- dataset %>% filter(호선 == sub_line[i]) %>% arrange(외부코드)
}

# 역명에 부제 있는 경우 제거
for (i in 1:length(key_list)) {
    Transfer <- rep(0, nrow(key_list[[i]]))
    key_list[[i]]$Transfer <- Transfer
    colnames(key_list[[i]]) <- c("Code", "Name", "Line", "ExCode", "CyCode", 
        "X", "Y", "lat", "long", "Transfer")
    sn <- key_list[[i]]$Name
    sn2 <- which(str_detect(sn, "[(]"))
    sn3 <- str_locate(sn[sn2], "[(]")
    sn[sn2] <- substr(sn[sn2], 1, sn3[, 1] - 1)
    key_list[[i]]$Name <- sn
}


# 지하철 순서화 및 분기점 정의 
# 1호선
key_list[["1"]] <- key_list[[1]][-c(which(key_list[[1]]$Name=="가산디지털단지"):which(key_list[[1]]$Name=="신창")), ]
key_list[["1-P"]] <- key_list[[1]][c(which(key_list[[1]]$Name=="구로"),which(key_list[[1]]$Name=="가산디지털단지"):which(key_list[[1]]$Name=="신창")), ]
key_list[["1-P"]]$Line <- "1-P"
key_list[["1-A"]] <- key_list[["1-P"]][c(which(key_list[["1-P"]]$Name=="금천구청"):which(key_list[["1-P"]]$Name=="광명")), ]
key_list[["1-A"]]$Line <- "1-A"
key_list[["1-B"]] <- key_list[["1-P"]][c(which(key_list[["1-P"]]$Name=="병점"):which(key_list[["1-P"]]$Name=="서동탄")), ]
key_list[["1-B"]]$Line <- "1-B"
key_list[["1-P"]] <- key_list[["1-P"]][-c(which(key_list[["1-P"]]$Name=="금천구청"), which(key_list[["1-P"]]$Name=="병점")), ]

subwayline <- list()
subwayline[["1"]] <- key_list[["1"]]
subwayline[["1-A"]] <- key_list[["1-A"]]
subwayline[["1-B"]] <- key_list[["1-B"]]
subwayline[["1-P"]] <- key_list[["1-P"]]

subwayline[["1"]]$Transfer <- c(rep(0, 13), "7", 0, 0, "4", rep(0,3), "6", 0, 0, "K", "K",
                                0, "2-A|UI", "6", "4", 0, "3|5", 0, "2", "4|K-A", 0, "K", 
                                0, 0, "5", 0, "2|2-B", "1-P", 0, 0, 0, "7", rep(0, 16))
subwayline[["1-A"]]$Transfer <- c("1-P", 0)
subwayline[["1-B"]]$Transfer <- c("1-P", 0)
subwayline[["1-P"]]$Transfer <- c(rep(0, 3), "1-A", rep(0, 4), "4", rep(0, 7), "1-B",
                                  rep(0, 18))

# 2호선
subwayline[["2"]] <- key_list[[2]]
subwayline[["2-A"]] <- key_list[[2]][c(which(key_list[[2]]$Name=="성수"):which(key_list[[2]]$Name=="신설동")), ]
subwayline[["2-A"]]$Line <- "2-A"
subwayline[["2-B"]] <- key_list[[2]][c(which(key_list[[2]]$Name=="신도림"):which(key_list[[2]]$Name=="까치산")), ]
subwayline[["2-B"]]$Line <- "2-B"
subwayline[["2"]] <- subwayline[["2"]][-c(which(key_list[[2]]$Name=="용답"):which(key_list[[2]]$Name=="신설동"), which(key_list[[2]]$Name=="도림천"):which(key_list[[2]]$Name=="까치산")), ]
subwayline[["2"]]$Transfer <- c(1, 0, 3, 5, 4, 6, 0, "5|B|K", 0, 0, "2-A", 7, 0, 0, 0, 8, 0,
                                9, 0, "B", 0, "S", 3, 0, 0, 4, 0, 0, 0, 0, 0, 0, 7, "1|2-B",
                                0, 5, 0, 6, "K", 0, 0, 0, "5")
subwayline[["2-A"]]$Transfer <- c(2, 0, 0, 0, "UI")
subwayline[["2-B"]]$Transfer <- c(2, 0, 0, 0, 0)

# 3호선
subwayline[["3"]] <- key_list[[3]]
subwayline[["3"]]$Transfer <- c(rep(0, 5), "K", rep(0, 6), "6-A", "6-A", rep(0, 6), "1|5", 
                                "2", "4", 0, "6", 0, "K", 0, 0, 0, "7|9", "2", 0, "S", 0,
                                "B", 0, 0, 0, 0, "B", "8", 0, "5-A")

# 4호선
subwayline[["4"]] <- key_list[[4]]
subwayline[["4"]]$Transfer <- c(0, 0, "7", "1", rep(0, 5), "UI", 0, 0, "1", "2|5", "3", 0, 
                                0, "1|K-A", 0, "6", 0, "K", 0, "7", "2", rep(0, 9), "1-P",
                                rep(0, 13))

# 5호선
subwayline[["5"]] <- key_list[[5]]
subwayline[["5-A"]] <- subwayline[["5"]][c(which(key_list[[5]]$Name=="강동"), which(key_list[[5]]$Name=="둔촌동"):which(key_list[[5]]$Name=="마천")), ]
subwayline[["5-A"]]$Line <- "5-A"
subwayline[["5"]] <- subwayline[["5"]][-c(which(key_list[[5]]$Name=="둔촌동"):which(key_list[[5]]$Name=="마천")), ]
subwayline[["5"]]$Transfer <- c(0, 0, 9, 0, 0, 0, 0, 0, "2-B", 0, 0, 0, 0, "2", 0, "1", 0, 
                                0, 0, "6|K", 0, "2", 0, 0, "1|3", "2", "2|4", "6", 0, 0, 
                                "2|B|K", 0, 0, 0, "7", 0, 0, "8", "5-A", 0, 0, 0, 0, 0)
subwayline[["5-A"]]$Transfer <- c(5, 0, 0, 0, 3, 0, 0, 0)

# 6호선
subwayline[["6"]] <- key_list[[6]]
subwayline[["6-A"]] <- subwayline[["6"]][c(which(key_list[[6]]$Name=="응암"):which(key_list[[6]]$Name=="구산")), ]
subwayline[["6-A"]]$Line <- "6-A"
subwayline[["6"]] <- subwayline[["6"]][-c(which(key_list[[6]]$Name=="역촌"):which(key_list[[6]]$Name=="구산")), ]
subwayline[["6"]]$Transfer <- c("6-A", 0, 0, "K", 0, 0, 0, "2", 0,  0, 0, "5|K", "K", "4", 0,
                                0, 0, 0, "3", "5", "2", "1", 0, "UI", 0, 0, 0, 0, 0, "1", "7",
                                0, 0)
subwayline[["6-A"]]$Transfer <- c(6, 0, 0, 0, 0, 0)

# 7호선
subwayline[["7"]] <- key_list[[7]]
subwayline[["7"]]$Transfer <- c(0, "1", 0, 0, "4", 0, 0, 0, "6", 0, 0, "K", 0, 0, 0, 0, "5",
                                0, "2", 0, 0, "B", 0, 0, 0, "3|9", 0, "4", rep(0, 7), "2", 0, 
                                "1-P", 0, 0, 0, "1", rep(0, 8), 0)


# 8호선
subwayline[["8"]] <- key_list[[8]]
subwayline[["8"]]$Transfer <- c(0, "5", 0, 0, "2", 0, 0, "3", 0, 0, "B", 0, 0, 0, 0, 0, "B")

# 9호선
subwayline[["9"]] <- key_list[[9]]
subwayline[["9"]]$Transfer <- c(0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 5, 0, 1, 0, 0, 4, 
                                0, 0, "3|7", 0, 0, 0, "B", 0, 0, 2)

# 분당선(B)
subwayline[["B"]] <- key_list[[11]]
subwayline[["B"]]$Transfer <- c("2|5|K", 0, 0, 7, 9, 2, 0, 3, 0, 0, 0, 3, 8, 0, 0, 8, 0, 0,
                                0, 0, "S", "S", 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, "1-P")

# 신분당선(S)
subwayline[["S"]] <- key_list[[18]]
subwayline[["S"]] <- subwayline[["S"]][c(which(key_list[[18]]$Name=="강남"):which(key_list[[18]]$Name=="양재시민의숲"), which(key_list[[18]]$Name=="청계산입구"):which(key_list[[18]]$Name=="광교")), ]
subwayline[["S"]]$Transfer <- rep(0, 12)
sub_migeum <- subwayline[["B"]][22, ]
sub_migeum[3] <- "S"
sub_migeum[10] <- "B"
subwayline[["S"]] <- rbind(subwayline[["S"]][1:6, ], sub_migeum, 
    subwayline[["S"]][7:12, ])
subwayline[["S"]]$Transfer <- c(2, 3, 0, 0, 0, "B", "B", 0, 0, 0, 0, 0, 0)

# 우이신설선(UI)
subwayline[["UI"]] <- key_list[[21]]
subwayline[["UI"]]$Transfer <- c(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 6, "1|2-A")

# 경의중앙선(K)
subwayline[["K"]] <- key_list[[16]]
subwayline[["K-A"]] <- subwayline[["K"]][c(which(key_list[[16]]$Name=="가좌"),which(key_list[[16]]$Name=="신촌"), which(key_list[[16]]$Name=="서울")), ]
subwayline[["K-A"]]$Line <- "K-A"
subwayline[["K"]] <- subwayline[["K"]][c(which(key_list[[16]]$Name=="지평"):which(key_list[[16]]$Name=="용산"), which(key_list[[16]]$Name=="효창공원앞"), which(key_list[[16]]$Name=="공덕"):which(key_list[[16]]$Name=="문산")), ]
subwayline[["K-A"]]$Transfer <- c("K", 0, 0)
subwayline[["K"]]$Transfer <- c(rep(0, 18), 7, 0, 1, 0, "2|5|B", 0, 3, 0, 0, 4, 1, 6, 5, 
                                0, 2, "K-A", 6, 0, 0, 0, 0, 0, 3, rep(0,12))




### 청량리 노선추가

data(transfer_station)
subway_data[["B"]]
subway_data[["1"]]
subway_data_DT[which(subway_data_DT$Name=="청량리"),"Transfer"] <- c("K|B", "1|B")
cheongryang <- subway_data[["K"]][22,]
cheongryang$Line <- "B"
cheongryang$Transfer <- "1|K"
subway_data_DT[which(subway_data_DT$Name=="왕십리"),]
subway_data[["K"]][22,]
subway_data[["B"]][1,"Dist"] <- geosphere::distHaversine(c(127.0377,37.56153), c(127.0468,37.58018))
subway_data[["B"]][1,"Time"] <- subway_data[["B"]][1,"Dist"]/566
cheongryang$Dist <- 0
cheongryang$Time <- 0
subway_data[["1"]][25,"Transfer"] <- "B|K"
subway_data[["K"]][22,"Transfer"] <- "1|B"
subway_data[["B"]] <- rbind(cheongryang, subway_data[["B"]])
subway_data_DT <- rbind(subway_data_DT, cheongryang[,colnames(subway_data_DT)])
transfer_station$Transfer[72] <- "1|B|K"
transfer_station
subway_data_DT[which(subway_data_DT$Name=="청량리"),]
save(file="data/subway_data_DT.RData", subway_data_DT)
save(file="data/subway_data.RData", subway_data)
save(file="data/transfer_station.RData", transfer_station)

1.2 역간 거리계산

이를 반영하기 위하여 데이터 구성단계에서 geosphere 패키지 내 distHaversine이라는 함수를 이용하였다.

(이는 지구가 둥글다는 것을 이용하여 두 지점 사이의 최단거리를 계산하는 방법)

Time 변수 고려시 지하철의 '표정속도(총 운행거리를 총 운행시간으로 나눈 것, 정차 시간도 운행시간에 포함된다.)'는 평균 34km/h 였다. 이를 반영하기 위해 566m/s로 계산하였다.

(https://www.insight.co.kr/newsRead.php?ArtNo=54171 인사이트 기사 참고)

for(i in 1:21){
  colnames(subwayline[[i]]) <- c("Code", "Name", "Line", "ExCode", "CyCode", 
        "X", "Y", "lat", "long", "Transfer", "Dist", "Time")
}

dist <- list()
for (i in seq_along(subwayline)) {
    d <- rep(0, 1, nrow(subwayline[[i]]))
    for (j in 2:nrow(subwayline[[i]])) {
        d[j] <- distHaversine(as.numeric(subwayline[[i]][j - 1, c("long","lat")]), 
            as.numeric(subwayline[[i]][j, c("long","lat")]))
    }
    dist[[i]] <- d
    dist[[i]] <- round(dist[[i]], 2)
}

for (i in seq_along(subwayline)) {
    subwayline[[i]]$Dist <- dist[[i]]
    subwayline[[i]]$Time <- round(as.numeric(dist[[i]]/566),2)
}

# 2호선은 순환형 구조이므로 시청역에 대하여 직접 입력
subwayline[["2"]][which(subwayline[["2"]]$Name=="시청"),"Dist"] <- distHaversine(
  as.numeric(subwayline[["2"]][which(subwayline[["2"]]$Name=="충정로"),c("long","lat")]),
  as.numeric(subwayline[["2"]][which(subwayline[["2"]]$Name=="시청"),c("long","lat")]))

subwayline[["2"]][which(subwayline[["2"]]$Name=="시청"),"Time"] <-
  round(subwayline[["2"]][which(subwayline[["2"]]$Name=="시청"),"Dist"] / 566,2)

head(subwayline[["2"]])

1.3 환승역마다 다른 시간을 고려한 데이터셋 구축

Depart_T <- str_sub(transfer_info$Transfer_Line,1,1)
Arrival_T <- str_sub(transfer_info$Transfer_Line,3,10)
Arrival_T <- str_replace(Arrival_T, "호선", "")
Arrival_T <- str_replace(Arrival_T, "우이경전철", "UI")
Arrival_T <- str_replace(Arrival_T, "경의중앙선", "K")
Arrival_T <- str_replace(Arrival_T, "분당선", "B")
Arrival_T <- str_replace(Arrival_T, "신B", "S")
transfer_info$Transfer_Line <- Depart_T
transfer_info$Transfer_Line2 <- Arrival_T
transfer_info <- transfer_info[-which(Transfer_Line2=="공항철도"),]
transfer_info <- transfer_info[-which(transfer_info$Transfer_Line2=="국철" & transfer_info$Transfer_Name%in%c("옥수","수서")), ]
transfer_info$Transfer_Line2 <- str_replace(transfer_info$Transfer_Line2, "국철", "1")
## 옥수, 수서 - > 국철 자료제외(과거 국철일때 정보 함유)
unique(transfer_info$Transfer_Line2)
transfer_info <- transfer_info[-which(transfer_info$Transfer_Line2%in%c("경춘선", "경인선", "인천1")),]
#"경원선", "경부선 : 의정부방향, 지선 그리고 1-P 을 나타냄
transfer_info$Transfer_Line2 <- str_replace(transfer_info$Transfer_Line2, "경원선", "1")
transfer_info$Transfer_Line2 <- str_replace(transfer_info$Transfer_Line2, "경부선", "1-P")
#transfer_info[which(transfer_info$Transfer_Line2=="지선"),]
transfer_info[30,"Transfer_Line2"] <- "2-B"
transfer_info[83,"Transfer_Line2"] <- "5-A"
transfer_info[which(transfer_info$Transfer_Name =="성수"),"Transfer_Line2"] <- "2-A"
#명칭 통일호
transfer_info$Transfer_Name <- str_replace(transfer_info$Transfer_Name, " ", "") 
transfer_info$Transfer_Name <- str_replace(transfer_info$Transfer_Name, "서울역", "서울")
transfer_info$Transfer_Name <- str_replace(transfer_info$Transfer_Name, "역사문화공원", "동대문역사문화공원")

subwayset <- data.frame(matrix(0,1,12))
colnames(subwayset) <- colnames(subwayline[[1]])
for(i in 1:21){
subwayset <- rbind(subwayset, subwayline[[i]])
}
subwayset <- subwayset[-1,]

subwayset$Transfer[-which(subwayset$Transfer=="0")]
subwayset$Transfer[str_which(subwayset$Transfer, "[|]")]

transfer_info[Transfer_Line2 %in% c("B", "S", "K", "UI", "9", "2-A", "2-B", "5-A", "6-A", "1-P"),]
add_transfer <- transfer_info[Transfer_Line2 %in% c("B", "S", "K", "UI", "9", "2-A", "2-B", "5-A", "6-A", "1-P"),c("Transfer_Name", "Transfer_Line2", "Transfer_Dist", "Transfer_Time", "Transfer_Line")]
colnames(add_transfer) <- colnames(transfer_info)
add_transfer_cir <- data.table("Transfer_Name"=c("충정로","응암", "응암", "구로", "구로"), 
                               "Transfer_Line"=c("2","6", "6-A", "1", "1-P"), "Transfer_Dist"= "0", 
                               "Transfer_Time" ="0", "Transfer_Line2" = c("2","6-A", "6", "1-P", "1"))

transfer_info <- rbind(transfer_info, add_transfer, add_transfer_cir)

minute_contain <- transfer_info$Transfer_Time[str_which(transfer_info$Transfer_Time, "분")]
minute_contain <- as.data.frame(minute_contain)
minute_contain <- minute_contain %>% separate(minute_contain, c("분","초"), "분")
minute_contain$<- str_remove(minute_contain$초, "초")
minute_contain$[which(minute_contain$=="")] <- 0
minute_contain$<- round(as.numeric(minute_contain$초)/60, 2)
minute_contain$<- as.numeric(minute_contain$분)
minute_contain <- minute_contain$+ minute_contain$초

second <- transfer_info$Transfer_Time[-str_which(transfer_info$Transfer_Time, "분")]
second <- str_remove(second, "초")
second <- round(as.numeric(second)/60,2)

transfer_info$Transfer_Time[-str_which(transfer_info$Transfer_Time, "분")] <- second
transfer_info$Transfer_Time[str_which(transfer_info$Transfer_Time, "분")] <- minute_contain

2. subway_shortestpath 함수 구성방법

시간을 기준으로 환승을 한다면 대개 3분정도의 다음 열차가 오기까지의 대기시간을 가진다.

이또한 반영해주기 위하여 환승을 하면 3분의 패널티를 추가로 입력하였다.



king4k1/Seoulsubway documentation built on Nov. 17, 2019, 4:08 p.m.