문제 : 부산 코로나 현황 사이트에 가서 코로나 신규 확진자 현황을 날짜별로 크롤링해서 그래프를 그리는 스크립트를 작성하시오.
## -- Attaching packages -- tidyverse 1.3.0 --
## √ ggplot2 3.3.2 √ purrr 0.3.4
## √ tibble 3.0.3 √ dplyr 1.0.2
## √ tidyr 1.1.2 √ stringr 1.4.0
## √ readr 1.3.1 √ forcats 0.5.0
## -- Conflicts ----- tidyverse_conflicts() --
## x dplyr::filter() masks stats::filter()
## x dplyr::lag() masks stats::lag()
## Loading required package: xml2
##
## Attaching package: 'rvest'
## The following object is masked from 'package:purrr':
##
## pluck
## The following object is masked from 'package:readr':
##
## guess_encoding
##
## Attaching package: 'lubridate'
## The following objects are masked from 'package:base':
##
## date, intersect, setdiff, union
##
## Attaching package: 'zoo'
## The following objects are masked from 'package:base':
##
## as.Date, as.Date.numeric
##
## Attaching package: 'scales'
## The following object is masked from 'package:purrr':
##
## discard
## The following object is masked from 'package:readr':
##
## col_factor
우선 부산시 코로나 발생 현황에 대한 자료를 부산시 홈페이지에서 가져온다.
url <- "http://www.busan.go.kr/covid19/Status.do"
covid <- read_html(url)
우선 부산시 url을 통해 HTML을 불러온 후 객체화 한다.
Sys.setlocale("LC_ALL", "English")
## [1] "LC_COLLATE=English_United States.1252;LC_CTYPE=English_United States.1252;LC_MONETARY=English_United States.1252;LC_NUMERIC=C;LC_TIME=English_United States.1252"
한글화 된 자료로 인한 오류를 위 코드를 통해 방지한다.
## X.U.B0A0..U.C9DC. X.U.B0A0..U.C9DC..1 X.U.D655..U.C9C4..U.C790..U.C218.
## 1 <U+B0A0><U+C9DC> <U+B0A0><U+C9DC> <U+D655><U+C9C4><U+C790><U+C218>
## 2 2020-11-25 <U+C218> 679
## 3 2020-11-24 <U+D654> 654
## 4 2020-11-23 <U+C6D4> 636
## 5 2020-11-22 <U+C77C> 631
## 6 2020-11-21 <U+D1A0> 627
## X.U.D655..U.C9C4..U.C790..U.C218..1
## 1 <U+B204><U+ACC4>
## 2 25
## 3 18
## 4 5
## 5 4
## 6 3
## X.U.C644..U.CE58..U.C790..U.C218...U.B204..U.ACC4..
## 1 <U+C644><U+CE58><U+C790><U+C218>(<U+B204><U+ACC4>)
## 2 589
## 3 584
## 4 582
## 5 578
## 6 578
## X.U.C0AC..U.B9DD..U.C790..U.C218...U.B204..U.ACC4..
## 1 <U+C0AC><U+B9DD><U+C790><U+C218>(<U+B204><U+ACC4>)
## 2 15
## 3 15
## 4 15
## 5 15
## 6 15
## X.U.AC80..U.C0AC..U.ACB0..U.ACFC..U.C74C..U.C131...U.B204..U.ACC4..
## 1 <U+AC80><U+C0AC><U+ACB0><U+ACFC><U+C74C><U+C131>(<U+B204><U+ACC4>)
## 2 167,836
## 3 167,644
## 4 167,026
## 5 166,639
## 6 166,177
## X.U.C790..U.AC00..U.ACA9..U.B9AC..U.D604..U.D669.
## 1 <U+C790><U+AC00><U+ACA9><U+B9AC><U+D604><U+D669>
## 2 4,007
## 3 3,751
## 4 3,521
## 5 3,408
## 6 3,322
## X.U.C790..U.AC00..U.ACA9..U.B9AC..U.D604..U.D669..1
## 1 <U+CD94><U+AC00>
## 2 56,844
## 3 56,668
## 4 56,494
## 5 56,370
## 6 56,085
행렬 불일치로 인한 오류는 fill = T 로 해결한다. 위 표를 통해 알 수 있듯이 2행의 데이터들은 쓸모가 없으며, 변수명을 좀 더 명확한 형태로 바꿔줘야 한다.
3.1. 데이터 전처리하기
covid_t <- covid_t[-c(1:1), ]
names(covid_t) <- c("date",
"day",
"culmalated",
"new",
"cured_cum",
"death_n_cum",
"test_n_cum",
"qrar",
"relased_cum")
head(covid_t)
## date day culmalated new cured_cum death_n_cum test_n_cum qrar
## 2 2020-11-25 <U+C218> 679 25 589 15 167,836 4,007
## 3 2020-11-24 <U+D654> 654 18 584 15 167,644 3,751
## 4 2020-11-23 <U+C6D4> 636 5 582 15 167,026 3,521
## 5 2020-11-22 <U+C77C> 631 4 578 15 166,639 3,408
## 6 2020-11-21 <U+D1A0> 627 3 578 15 166,177 3,322
## 7 2020-11-20 <U+AE08> 624 6 575 15 165,612 3,324
## relased_cum
## 2 56,844
## 3 56,668
## 4 56,494
## 5 56,370
## 6 56,085
## 7 55,856
2행의 필요없는 행은 인덱싱을 통해 삭제하며, 각 변수의 이름도 간단한 형태로 바꿔준다.
변수명
date = 날짜
day = 요일
culmalated = 총 확진자 수
new = 추가 확진자 수
cured_cum = 완치자 수(누계)
death_n_cum = 총 사망자 수(누계)
test_n_cum = 검사 결과 음성(누계)
quer = 격리 중 인원
relased = 격리 해제 인원
3.2. 데이터 전처리하기2
str(covid_t)
## 'data.frame': 279 obs. of 9 variables:
## $ date : chr "2020-11-25" "2020-11-24" "2020-11-23" "2020-11-22" ...
## $ day : chr "<U+C218>" "<U+D654>" "<U+C6D4>" "<U+C77C>" ...
## $ culmalated : chr "679" "654" "636" "631" ...
## $ new : chr "25" "18" "5" "4" ...
## $ cured_cum : chr "589" "584" "582" "578" ...
## $ death_n_cum: chr "15" "15" "15" "15" ...
## $ test_n_cum : chr "167,836" "167,644" "167,026" "166,639" ...
## $ qrar : chr "4,007" "3,751" "3,521" "3,408" ...
## $ relased_cum: chr "56,844" "56,668" "56,494" "56,370" ...
변수들의 속성을 살펴보면 우리가 이용해야 할 변수들의 데이터가 ‘chr’ 속성임을 알 수 있다. 분석에 필요한 변수인 date와 new(그리고 culmalated)의 속성을 ’num’으로 변환해줄 필요가 있다.
attach(covid_t)
covid_t$new <- as.numeric(new)
covid_t$culmalated <- as.numeric(culmalated)
covid_t$date <- as.Date(date)
편의를 위해 attach()를 이용해 변수들을 분리하여 필요한 변수들의 속성을 바꿔준다.
class(covid_t$date)
## [1] "Date"
class(covid_t$new)
## [1] "numeric"
class(covid_t$culmalated)
## [1] "numeric"
변수들의 속성이 잘 변환되었는지 확인한다.
4.1. 데이터 추출하기
busan_c<- covid_t %>%
select(date,new,culmalated)
tail(busan_c)
## date new culmalated
## 275 2020-02-26 6 57
## 276 2020-02-25 13 51
## 277 2020-02-24 22 38
## 278 2020-02-23 11 16
## 279 2020-02-22 3 5
## 280 2020-02-21 2 2
날짜, 신규 감염자 수, 전체 감염자 수 변수 데이터만 추출하여 하위 데이터를 구성하고, 이를 확인한다.
(TRC는 오류 때문에 “TRC”라고 입력)
4.2. 일일 신규 확진자 수 그래프 그리기
busan_c %>%
ggplot(mapping = aes(x = date, y = new))+
geom_line(alpha = 0.5,
color = 'blue')+
geom_point(color = 'red',
alpha = 0.5,
size = 1.2)+
labs(x = 'date',
y = 'new')+
ggtitle('daily infected person
number')+
scale_x_date(breaks = '1 month',
date_labels = '%b')
4.3. 전체 확진자 수 그래프 그리기
busan_c %>%
ggplot(mapping = aes(x = date, y = culmalated))+
geom_line(alpha = 0.5,
size = 1.2,
color = 'yellow')+
geom_bar(stat = 'identity',
color = 'orange',
fill = "yellow")+
labs(x = 'date',
y = 'culmalated')+
ggtitle('total infected person
number')+
scale_x_date(breaks = '1 month',
date_labels = '%b')
\[결론\] 일일 신규 확진자의 추이를 보면, 3월에 잠시 불안정했다가 8월까지 다소 안정적인 추이를 보여준다. 하지만 환절기가 시작되는 9월 부터 신규 확진자가 다시 증가하는 모습을 보이는데, 특히 10월 중순의 최고 규모의 신규확진자가 발생했음을 알 수 있다. 또한 전제 확진자 수의 그래프를 보면 8월 중순부터 전체 확진자 수가 급증하는 것을 알 수 있다.
busan_c %>%
mutate(ma = rollmean(new, 7,
aligh = 'right',
fill = 0)) %>%
ggplot(aes(x = date))+
geom_col(aes(y = new),
fill = 'white',
color = 'orange',
size = 0.2)+
geom_line(aes(y = ma),
color = 'steelblue',
size = 1)+
geom_area(aes(y = ma),
color = 'yellow',
alpha =0.5)+
scale_x_date(breaks = '1 month',
date_labels = '%b')+
scale_y_log10()+
labs(x = 'Date',
y = 'Newly confirmed cases',
title = '3ed COVID-19 wave in Busan',
subtitle = 'Red line: 7-day moving average')+
theme_minimal()