그동안 ADsP공부한다고, 또 중간기말 공부한다고 R에서 손을 놨었다. 물론 변명이겠지만 ㅠㅠ
아무튼 그 전에 했었던 공유자전거 데이터 분석을 좀 더 진행해봤다. 추가되는데 실질적으로 소모한 시간은 5시간(?)정도 인 것 같다.
어제 카페가서 3시간+엊그제와 오늘 야금야금?해서 순수하게 코드입력하는데 쓴 시간은 5~6시간으로 보인다.
비루한 전체 코드는 github에 추가해놓았다. 꺠짝깨작 주석을 달아놨으니 다른 사람에게도 도움이 되길 바란다.
https://github.com/SangdoDong/my-R-code
1 2 3 4 5 | library(ggplot2) library(lubridate) #날짜 및 시간핸들링 패키지 library(dplyr) library(plotly) | cs |
12 str(bike)cs 'data.frame': 132427 obs. of 16 variables: $ Trip.ID : int 1912818 1919661 1933383 1944197 1940317 1944075 1944073 1944067 1944062 1944063 ... $ Duration : int 180 1980 300 10860 420 780 600 600 2880 960 ... $ Start.Time : Factor w/ 97997 levels "2016-07-07T04:17:00",..: 1 2 3 4 5 5 6 7 8 8 ... $ End.Time : Factor w/ 90933 levels "2016-07-07T04:20:00",..: 1 2 3 20 4 5 5 7 23 12 ... $ Starting.Station.ID : int 3014 3014 3016 3016 3032 3021 3022 3076 3031 3031 ... $ Starting.Station.Latitude : num 34.1 34.1 34.1 34.1 34 ... $ Starting.Station.Longitude: num -118 -118 -118 -118 -118 ... $ Ending.Station.ID : int 3014 3014 3016 3016 3032 3054 3014 3005 3031 3078 ... $ Ending.Station.Latitude : num 34.1 34.1 34.1 34.1 34 ... $ Ending.Station.Longitude : num -118 -118 -118 -118 -118 ... $ Bike.ID : int 6281 6281 5861 5861 6674 6717 5721 5957 6137 6351 ... $ Plan.Duration : int 30 30 365 365 0 30 30 365 365 30 ... $ Trip.Route.Category : Factor w/ 2 levels "One Way","Round Trip": 2 2 2 2 2 1 1 1 2 1 ... $ Passholder.Type : Factor w/ 4 levels "Flex Pass","Monthly Pass",..: 2 2 1 1 4 2 2 1 1 2 ... $ Starting.Lat.Long : Factor w/ 126 levels "","{'longitude': '-118.231277', 'latitude': '34.034801', 'needs_recoding': False}",..: 19 19 32 32 81 18 6 72 63 63 ... $ Ending.Lat.Long : Factor w/ 128 levels "","{'longitude': '-118.231277', 'latitude': '34.034801', 'needs_recoding': False}",..: 19 19 32 32 81 17 19 96 63 29 ...
bike로 저장한 데이터는 16개의 칼럼과 132,427개의 열로 구성되어있다.
Flex Pass Monthly Pass Staff Annual Walk-up
1 table(bike$Passholder.Type)cs
9517 81304 382 41224passholder의 타입은 flex pass, monthly pass, staff Annual, walk-up 으로 총 4개로 구성된다.
각 사용자타입별로 이용시간을 알고 싶었다.
123 bike$usetime<-ymd_hms(bike$End.Time)-ymd_hms(bike$Start.Time)bike$usetime<-as.numeric(bike$usetime)summary(bike$usetime)cs
종료시간-시작시간 을 계산하여 실제로 이용한 시간이 나왔다.
이미 usetime이 numeric 형식이었는데 확실하게 하고자 다시 한 번 입력했던 것 같다.
Min. 1st Qu. Median Mean 3rd Qu. Max.
1.00 6.00 10.00 28.19 18.00 8188.00
summary를 통해 확인해본 요약치는 값이 이상하다는 것을 확인할 수 있다. 특히 max의 값이 8188으로
자전거를 8188분이나 탔다는 것은 이상치라고 생각했다.
1 boxplot(bike$usetime)$statscs
[,1]
[1,] 1
[2,] 6
[3,] 10
[4,] 18
[5,] 36
박스플롯 명령어를 입력하여 일반적이라고 여겨지지 않는 데이터를 제거했다. 명령어는 다음과 같다.
12345 bike$usetime<-ifelse(bike$usetime<=1|bike$usetime>=36,NA, bike$usetime)table(is.na(bike$usetime))cs FALSE TRUE 118494 13933
1 bike<- bike %>% filter(!is.na(usetime))cs
이용시간이 1분이하와 36분 이상 탄 데이터를 날려버렸다
그러니깐 NA값으로 나온 것이 13933개나 되었다. 기존데이터에 10%가 좀 넘는 값이다.
물론 자전거를 더 오래타는 사람이 있을 것이기 때문에 이러한 점을 고려해서 제거했어야한다.
이후 ggplot을 이용해 이용자별 이용시간을 그림으로 나타내었다.
123 ggplot(data=bike, aes(x=Passholder.Type, y=usetime))+geom_boxplot()+ggtitle("usetime by pass holder")cs
사용자별 이용시간을 한 눈에 파악할 수 있다.
123 hist(bike$usetime, breaks = 30,main = "Using time", col = "yellow", xlab="time", ylab = "number")cs
히스토그램을 통해 전체이용자의 사용시간 빈도를 파악할 수 있다.
이후 사용시간에 따른 빈도수를 히스토그램으로 그렸다. 여기까지는 앞 전에 썼던 글과 내용의 차이가 없다.
다음으로 알고 싶었던 내용은 round trip과 one way 에서 어떤 차이가 있는가 였다.
Trip route category를 보면 그 round trip과 one way로 구분되어 있는 것을 확인할 수 있다.
먼저 다음과 같은 명령어로 round trip만을 뽑아보았다.
123 round_journey<- bike %>%filter(Trip.Route.Category=="Round Trip")cs 이후 정의된 데이터로 이용자별 평균 사용시간값을 계산했다.
1234 round_journey %>%group_by(Passholder.Type) %>%summarise(mean=mean(usetime))cs
# A tibble: 4 x 2
Passholder.Type mean
<fct> <dbl>
1 Flex Pass 16.3
2 Monthly Pass 14.1
3 Staff Annual 10.4
4 Walk-up 22.4
이후 위와 같은 데이터가 나오는 것을 확인할 수 있다.
사용자별 공유자전거 사용시간의 통계를 한 눈에 파악하기 위해서 시각화 작업을 했다.
#1.1 round_journey의 passholder type별 사용통계
12 ggplot(data=round_journey, aes(x=Passholder.Type, y=usetime))+geom_boxplot()+ggtitle("round_journey")cs
마찬가지 방식으로 oneway 루트도 아래와 같이 oneway루트만을 추출한 후 평균을 계산했다.
#2. onewaytrip 평균이용시간
1234567 oneway_journey<- bike %>%filter(Trip.Route.Category=="One Way")oneway_journey %>%group_by(Passholder.Type) %>%summarise(mean=mean(usetime))cs # A tibble: 4 x 2
Passholder.Type mean
<fct> <dbl>
1 Flex Pass 16.3
2 Monthly Pass 14.1
3 Staff Annual 10.4
4 Walk-up 22.4
이제 위와 같은 결과가 나온다. 위와 같은 결과를 다음 코드를 통해 그림을 나타내었다.
123 #2.1 oneway_journey의 passholder type별 사용통계ggplot(data=oneway_journey, aes(x=Passholder.Type, y=usetime))+geom_boxplot()+ggtitle("oneway_journey")cs
다음으로 알고 싶던 내용은 어떤 station이 얼마나 많은 자전거가 반납되고 또 빌려지는지 였다.
해당 내용을 알기 위해서는 각 station별로 빌리는 자전거의 수와 또 반납되는 자전거 수를 파악해야한다.
round trip의 경우 동일 station에서 빌려지고 반납되기 때문에 문제가 되지않으나,
one way의 경우 한 station에서 과도하게 많이 반납되거나 혹은 과도하게 많은 자전거 수요가 있다면, 초과공급 혹은
초과수요가 발생한다. 따라서 이를 해결하기위해 자전거 공유업체에서는 과도하게 많은 반납이 이루어지는 station에서
자전거를 회수해서 자전거가 부족한 station을 파악해야한다.
1234 #oneway 중에서 starting.station id와 passholder type만을 추출.oneway_starting_station_id<- bike %>%filter(Trip.Route.Category=="One Way") %>%select(Starting.Station.ID,Passholder.Type)cs
명령어를 통해 one way 에 해당하는 데이터에서 station아이디와 passholder타입을 추출해서
새로운 변수로 지정했다.
이후 지정한 변수를 바탕으로 다음과 같은 방식으로 station id를 카운팅하였다.
1234 #추출한 데이터에서 starting station ID 횟수oneway_starting_station_count<-oneway_starting_station_id %>%group_by(Starting.Station.ID) %>%tally()cs 동일한 방식으로 반납이 이루어진 station id를 카운팅했다.
12345678 #oneway중에서 ending station id와 passholder type만을 추출oneway_ending_station_id<- bike %>%filter(Trip.Route.Category=="One Way") %>%select(Ending.Station.ID, Passholder.Type)#추출한 데이터에서 ending station id 횟수oneway_ending_station_count<-oneway_ending_station_id %>%group_by(Ending.Station.ID) %>%tally()cs
이후 아래 스크립트와 같이 진행했다.
복사본에 변수명을 비교적 간단하게 바꾸고 불필요한 데이터를 제거하는 작업을 수행했다.
마지막으로 total이라는 변수명으로 데이터를 합쳤다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | #데이터 통합을 위한 변수명 일치시키기 #시작스테이션데이터 starting_count_new<-oneway_starting_station_count #복사본 만들기. starting_count_new<-rename(starting_count_new, station = Starting.Station.ID) #변수명 변경 starting_count_new<-rename(starting_count_new, startcount = n) #종료스테이션데이터 ending_count_new<-oneway_ending_station_count #복사본 만들기 #변수명 변경 ending_count_new<-rename(ending_count_new, station = Ending.Station.ID) ending_count_new<-rename(ending_count_new, endingcount = n) #불필요한 데이터 제거 starting_count_new<-starting_count_new[-c(65,66),] ending_count_new<-ending_count_new[-c(65,66),] #데이터합치기 total<-left_join(starting_count_new, ending_count_new, by="station") | cs |
1 2 3 4 5 6 7 8 9 10 11 | total_1<-melt(total, id=(c("station"))) head(total_1) View(total_1) f1<-ggplot(data=total_1, aes(x=station)) f2<-f1+geom_bar(aes(y=startcount), colour="Red", size=1) f3<-f2+geom_bar(aes(y=endingcount), colour="blue", size=1) head(total_1) h1<-ggplot(data=total_1, aes(x=station, y=value, fill=variable))+geom_bar(stat="identity", position = "dodge") | cs |
따라서 위 그림을 통해 해당 station에서 대여된 자전거 수, 반납된 자전거 수의 차이를 한 눈에 비교할 수 있다.
'R programming' 카테고리의 다른 글
2016년도 진료내역을 통한 상위 질병 확인해보기 (0) | 2019.03.06 |
---|---|
학생 시험성적 t-test 및 아노바 (0) | 2019.02.14 |
개인 의료비 예측하기 (0) | 2018.10.15 |
공유자전거 데이터 분석하기 (0) | 2018.09.28 |
문과생 R 프로그래밍 입문하기 (0) | 2018.09.28 |