브런치 글 [생활 속 데이터분석] (주차장에) 제 자리 있나요? https://brunch.co.kr/@llun/23의 코드입니다.
브런치 플랫폼상 코드 복사가 안 되고 하이라이트 기능이 없는 한계가 있어 마크다운으로 제공합니다.
# URL을 통해 가져옴
content <- GET("https://www.sisul.or.kr/open_content/parking/guidance/useable.jsp")
# 셀 내용 읽어오기 - 파이프를 이용하여 한번에 연결
useable_df <- read_html(content) %>%
html_nodes("table tr td") %>%
html_text() %>%
matrix(ncol = 4, byrow = TRUE) %>%
as.data.frame()
# 열 이름(colnames)도 가져와보자
colnames(useable_df) <- read_html(content) %>% html_nodes("table tr th") %>% html_text()
# 현재시간(크롤링 시각) 추가 & datetime이라는 이름의 시각 열을 추가
useable_df$datetime <- format(Sys.time(), tz="Asia/Seoul", usetz=TRUE)
# 크롤링 작업한 데이터 확인
kable(useable_df)
| 번호 | 주차장명 | 주차면수 | 잔여주차가능대수 | datetime |
|---|---|---|---|---|
| 1 | 잠실역 | 357 | 305 | 2019-08-18 05:05:55 KST |
| 2 | 구로디지털단지역 | 92 | 57 | 2019-08-18 05:05:55 KST |
| 3 | 개화산역 | 322 | 251 | 2019-08-18 05:05:55 KST |
| 4 | 수서역북 | 570 | 471 | 2019-08-18 05:05:55 KST |
| 5 | 수서역남 | 22 | 20 | 2019-08-18 05:05:55 KST |
| 6 | 복정역 | 363 | 312 | 2019-08-18 05:05:55 KST |
| 7 | 한강진역 | 176 | 144 | 2019-08-18 05:05:55 KST |
| 8 | 수락산역 | 157 | 108 | 2019-08-18 05:05:55 KST |
| 9 | 화랑대역 | 332 | 277 | 2019-08-18 05:05:55 KST |
| 10 | 구파발역 | 399 | 348 | 2019-08-18 05:05:55 KST |
| 11 | 신설동공영 | 79 | 3 | 2019-08-18 05:05:55 KST |
| 12 | 영등포구청역 | 137 | 74 | 2019-08-18 05:05:55 KST |
| 13 | 적선노외 | 600 | 591 | 2019-08-18 05:05:55 KST |
| 14 | 학여울역 | 180 | 122 | 2019-08-18 05:05:55 KST |
| 15 | 사당노외 | 184 | 102 | 2019-08-18 05:05:55 KST |
| 16 | 종묘 | 1316 | 1259 | 2019-08-18 05:05:55 KST |
| 17 | 천왕역 | 328 | 239 | 2019-08-18 05:05:55 KST |
| 18 | 개화역 | 483 | 383 | 2019-08-18 05:05:55 KST |
| 19 | 마포유수지 | 505 | 402 | 2019-08-18 05:05:55 KST |
| 20 | 세종로 | 1260 | 1139 | 2019-08-18 05:05:55 KST |
| 21 | 신대방역 | 60 | 18 | 2019-08-18 05:05:55 KST |
| 22 | 동대문 | 1092 | 1056 | 2019-08-18 05:05:55 KST |
| 23 | 천호역 | 1430 | 860 | 2019-08-18 05:05:55 KST |
| 24 | 용산주차빌딩 | 561 | 411 | 2019-08-18 05:05:55 KST |
| 25 | 신천유수지 | 221 | 174 | 2019-08-18 05:05:55 KST |
| 26 | 서울역관광버스주차장 | 33 | 35 | 2019-08-18 05:05:55 KST |
| 27 | 신방화역 | 199 | 132 | 2019-08-18 05:05:55 KST |
| 28 | 훈련원공원 | 873 | 1038 | 2019-08-18 05:05:55 KST |
| 29 | 가양라이품 | 38 | 34 | 2019-08-18 05:05:55 KST |
| 30 | 흑석동공영 | 107 | 81 | 2019-08-18 05:05:55 KST |
| 31 | 웃우물공영 | 39 | 30 | 2019-08-18 05:05:55 KST |
| 32 | 장안2동 | 39 | 10 | 2019-08-18 05:05:55 KST |
When you click the Knit button a document will be generated that includes both content as well as the output of any embedded R code chunks within the document. You can embed an R code chunk like this:
# 데이터를 불러올 수 있는 다양한 방법
# useable_df <- read_excel("~/R/useable_df.xlsx")
# useable_df <- read_csv("번호,주차장명,주차면수,잔여주차가능대수
# 1,잠실역,357,305
# 2,구로디지털단지역,92,51
# 3,개화산역,322,258
# 4,수서역북,570,467
# 5,수서역남,22,20
# 6,복정역,363,315
# 7,한강진역,176,138
# 8,수락산역,157,108
# 9,화랑대역,332,275
# 10,구파발역,399,348
# 11,신설동공영,79,3
# 12,영등포구청역,137,74
# 13,적선노외,600,591
# 14,학여울역,180,121
# 15,사당노외,184,98
# 16,종묘,1316,1260
# 17,천왕역,328,240
# 18,개화역,483,387
# 19,마포유수지,505,403
# 20,세종로,1260,1139
# 21,신대방역,60,18
# 22,동대문,1092,1053
# 23,천호역,1430,841
# 24,용산주차빌딩,561,411
# 25,신천유수지,221,175
# 26,서울역관광버스주차장,33,35
# 27,신방화역,199,131
# 28,훈련원공원,873,1037
# 29,가양라이품,38,35
# 30,흑석동공영,107,80
# 31,웃우물공영,39,31
# 32,장안2동,39,10")
# 에러 발생
try(gvisColumnChart(useable_df %>% select(`주차면수`, `잔여주차가능대수`)))
## Error in gvisCheckCoreChartData(data, xvar = xvar, yvar = yvar) :
## Error: Your data has to have at least one numerical column.
데이터가 숫자 형태가 아니라며 에러가 나네요. str() 함수로 살펴보니 factor형입니다.
# 데이터 구조(structure) 확인
str(useable_df)
## 'data.frame': 32 obs. of 5 variables:
## $ 번호 : Factor w/ 32 levels "1","10","11",..: 1 12 23 27 28 29 30 31 32 2 ...
## $ 주차장명 : Factor w/ 32 levels "가양라이품","개화산역",..: 22 4 2 14 13 8 29 12 30 5 ...
## $ 주차면수 : Factor w/ 31 levels "107","1092","1260",..: 18 31 14 26 12 19 8 7 17 22 ...
## $ 잔여주차가능대수: Factor w/ 32 levels "10","102","1038",..: 19 28 15 27 13 20 10 5 16 22 ...
## $ datetime : chr "2019-08-18 05:05:55 KST" "2019-08-18 05:05:55 KST" "2019-08-18 05:05:55 KST" "2019-08-18 05:05:55 KST" ...
You can also embed plots, for example:
# 형식 변경 전 사본으로 복사
charting <- useable_df
# as.numeric() 또는 as.integer()로 형변환
charting$`주차면수` <- as.integer(charting$`주차면수`)
charting$`잔여주차가능대수` <- as.integer(charting$`잔여주차가능대수`)
그런 다음 차트를 그려주면,
Column <- gvisColumnChart(charting %>% select(-`번호`))
plot(Column)
주차 면수 즉, capacity가 파란색이고 가능 대수(빈자리)가 빨간색인데 들쭉날쭉한 게 눈에 잘 안 들어옵니다. 차트 종류를 바꿔봅니다.
Area <- gvisAreaChart(charting %>% select(-`번호`))
plot(Area)
훨씬 낫습니다. 그런데 잔여 대수가 주차면수보다 많을 리가 없을 텐데요. y축 단위도 뭔가 이상하면서 익숙합니다. 주차장 개수와 동일하게 데이터 한 세트가 32줄로 이뤄져있는데 공교롭게도 그 언저리 숫자네요.
str(charting)
‘data.frame’:32 obs. of 5 variables:
$ 번호 : Factor w/ 32 levels “1”,“10”,“11”,..: 1 12 23 27 28 29 30 31 32 2 …
$ 주차장명 : Factor w/ 32 levels “가양라이품”,“개화산역”,..: 22 4 2 14 13 8 29 12 30 5 …
$ 주차면수 : num 18 31 14 26 12 19 8 7 17 22 …
$ 잔여주차가능대수: num 14 21 12 23 7 16 8 2 13 18 …
데이터 자체가 문제였습니다. 저 위에 factor일 때와 값이 아예 달라졌네요. 숫자를 정확한 값으로 바꿔줍니다. {factor to integer r - Google Search} 가장 직관적인 솔루션은 문자형으로 먼저 변환 후 숫자로 한번 더 변환하는 것입니다.
# charting 데이터를 다시 불러온 뒤 실행(이미 데이터값에 오류가 생겼으므로)
charting <- useable_df
charting$`주차면수` <- as.numeric(as.character(charting$`주차면수`))
charting$`잔여주차가능대수` <- as.numeric(as.character(charting$`잔여주차가능대수`))
# charting$주차장명 <- as.character(charting$주차장명)
Column <- gvisColumnChart(charting %>% select(`주차장명`, `주차면수`, `잔여주차가능대수`))
plot(Column)
Area <- gvisAreaChart(charting %>% select(`주차장명`, `주차면수`, `잔여주차가능대수`))
plot(Area)
차트로 그려놓으니 뭔가 그럴싸해 보이기도 하고 원하는 시간대 주차현황을 알 수 없으니 별 소득이 없는 것도 같습니다. 여유가 된다면 위 차트를 시간단위로 모두 그려서 애니메이션처럼 만들어도 괜찮겠네요.
하지만 아직 소기의 목적을 달성하지 못했습니다.
Note that the echo = FALSE parameter was added to the code chunk to prevent printing of the R code that generated the plot.