코로나19 대쉬보드 1
코로나19(covid-19) 관련 다양한 실시간 정보 및 현황을 다음 웹사이트를 통해서 얻을 수 있다.
Tidyverse Korea
데이터
제작 방법과 배포
연락방법
제작방법에 대해서 궁금하신 점이나 참여를 원하시는 분은 issues에 남겨주시거나 Tidyverse Korea 페북그룹으로 연락주세요.
---
title: "코로나19"
subtitle: "대쉬보드"
output:
flexdashboard::flex_dashboard:
orientation: rows
theme: readable
social: menu
source_code: embed
vertical_layout: fill
editor_options:
chunk_output_type: console
---
```{r setup, include=FALSE}
library(flexdashboard)
library(tidyverse)
library(janitor)
library(coronavirus)
library(extrafont)
loadfonts()
world <- coronavirus %>%
clean_names() %>%
group_by(country_region, type) %>%
summarise(total = sum(cases)) %>%
pivot_wider(names_from = type,
values_from = total) %>%
arrange(-confirmed) %>%
ungroup() %>%
mutate(country = case_when(country_region == "United Arab Emirates" ~ "UAE",
country_region == "Mainland China" ~ "China",
country_region == "North Macedonia" ~ "N.Macedonia",
TRUE ~ country_region) %>% trimws()
) %>%
mutate_if(is.character, factor)
world_daily <- coronavirus %>%
dplyr::group_by(date, type) %>%
summarise(total = sum(cases, na.rm = TRUE)) %>%
pivot_wider(names_from = type,
values_from = total) %>%
arrange(date) %>%
ungroup() %>%
mutate(confirmed_cum = cumsum(confirmed),
death_cum = cumsum(death),
recovered_cum = cumsum(recovered))
```
전세계 {data-icon="fa-globe"}
===================================
Row
--------------------------------------------
### 검사자수 {.value-box}
```{r tested}
valueBox(NA,
icon = "fa-vial",
color = "primary")
```
### 확진자수 {.value-box}
```{r infected}
confirmed <- world %>% summarise(sum(confirmed, na.rm=TRUE)) %>% pull
valueBox(scales::comma(confirmed),
icon = "fa-procedures",
color = "warning")
```
### 사망자수 {.value-box}
```{r death}
death <- world %>% summarise(sum(death, na.rm=TRUE)) %>% pull
valueBox(scales::comma(death),
icon = "fa-skull",
color = "danger")
```
### 회복자수 {.value-box}
```{r recovered}
recovered <- world %>% summarise(sum(recovered, na.rm=TRUE)) %>% pull
valueBox(scales::comma(recovered),
icon = "fa-walking",
color = "success")
```
Row
-----------------------------------------------------------------------
### 국가/유형별 사례수
```{r world_summary}
library(highcharter)
highchart() %>%
hc_chart(type = "column") %>%
hc_plotOptions(column = list(stacking = "normal")) %>%
hc_xAxis(categories = world$country) %>%
hc_yAxis(type = 'logarithmic') %>%
hc_add_series(name="사망",
data = world$death,
stack = "코로나") %>%
hc_add_series(name="회복",
data = world$recovered,
stack = "코로나") %>%
hc_add_series(name="확진",
data = world$confirmed,
stack = "코로나") %>%
hc_legend(enabled = TRUE) %>%
hc_tooltip(pointFormat = '{point.y} 명') %>%
hc_add_theme(hc_theme_538())
```
Row {data-width=400}
-------------------------------------
### 유형별 일별 누적 사례수
```{r time-series-plot}
library(xts)
library(dygraphs)
world_cum_daily <- world_daily %>%
select(날짜 = date,
확진 = confirmed_cum,
사망 = death_cum,
회복 = recovered_cum)
world_daily_xts <- xts(world_cum_daily[ ,-1], order.by=as.POSIXct(world_cum_daily$날짜))
FUNC_JSFormatNumber <- "function(x) {return x.toString().replace(/(\\d)(?=(\\d{3})+(?!\\d))/g, '$1,')}"
dygraph(world_daily_xts) %>%
dyHighlight(highlightCircleSize = 5,
highlightSeriesBackgroundAlpha = 0.2,
hideOnMouseOut = FALSE) %>%
dyRangeSelector(height = 20) %>%
dyAxis("x", drawGrid = FALSE) %>%
dyAxis("y", axisLabelFormatter=JS(FUNC_JSFormatNumber),
valueFormatter=JS(FUNC_JSFormatNumber)) %>%
dyOptions(includeZero = TRUE,
axisLineColor = "navy",
gridLineColor = "lightblue") %>%
dySeries("확진", label = "확진") %>%
dyLegend(width=400, show = "always", hideOnMouseOut = FALSE) %>%
dyAnnotation("2020-02-17", text = "신천지 31번")
```
### 지역별 사례수 {data-width=400}
```{r corona-leaflet, eval=TRUE}
library(leaflet)
world_map <- coronavirus %>%
clean_names() %>%
mutate(country = case_when(country_region == "United Arab Emirates" ~ "UAE",
country_region == "Mainland China" ~ "China",
country_region == "North Macedonia" ~ "N.Macedonia",
TRUE ~ country_region) %>% trimws()
) %>%
group_by(country, type) %>%
summarise(cases = sum(cases)) %>%
spread(type, cases, fill = 0L)
world_map_df <- map_data("world") %>%
group_by(region) %>%
summarise(long = mean(long),
lat = mean(lat)) %>%
right_join(world_map, by=c("region" = "country"))
# world_map_df %>%
# leaflet() %>%
# addTiles() %>%
# addProviderTiles(providers$OpenStreetMap) %>%
# addMarkers(lng=~long, lat=~lat, clusterOptions = markerClusterOptions(),
# popup = ~ as.character(paste0(" 코로나19 현황: ", region, "
",
# "-----------------------------------------------------------
",
# "· 감염: ", scales::comma(confirmed), "
",
# "· 사망: ", scales::comma(death), "
",
# "· 회복: ", scales::comma(recovered), "
")))
# map_data <- get_data_from_map(download_map_data("custom/world-eckert3-highres"))
hcmap("custom/world-eckert3-highres", data = world_map_df, value = "confirmed",
joinBy = c("name", "region"), name = "코로나19",
dataLabels = list(enabled = TRUE, format = '{point.name}'),
borderColor = "#FAFAFA", borderWidth = 0.1,
tooltip = list(valueDecimals = 0, valueSuffix = " 명"))
```
한국 {data-icon="fa-map"}
===================================
Row {data-width=150}
--------------------------------------------
```{r ingest-corona-google, warning=FALSE, eval=FALSE}
## 데이터셋 --------------------
library(googlesheets4)
library(tidyverse)
library(lubridate)
cv_kor <- read_sheet('https://docs.google.com/spreadsheets/d/1fODH5PZJw9jxwV2GRe85BRQgc3mxdyyIpQ0I6MDJKXc/edit#gid=0')
cv_kor_df <- cv_kor %>%
select(날짜, 확진자=`누적 확진자수`, 검사자 = `누적 검사자수`, 사망자, 회복자=`누적 격리해제`) %>%
arrange(날짜) %>%
mutate(일자 = as.Date(날짜)) %>%
group_by(일자) %>%
summarise(검사자 = last(검사자),
확진자 = last(확진자),
사망자 = last(사망자),
회복자 = last(회복자)
) %>%
padr::pad(.)
cv_kor_df %>%
write_rds("data/cv_kor_df.rds")
```
### 검사자수
```{r kor-tested}
cv_kor_df <-
read_rds("data/cv_kor_df.rds")
kor_tested <- cv_kor_df %>%
select(검사자) %>%
slice(n()) %>% pull
valueBox(scales::comma(kor_tested),
icon = "fa-vial",
color = "primary")
```
### 확진자수
```{r kor-infected}
kor_infected <- cv_kor_df %>%
select(확진자) %>%
slice(n()) %>% pull
valueBox(scales::comma(kor_infected),
icon = "fa-procedures",
color = "warning")
```
### 사망자수
```{r kor-death}
kor_death <- cv_kor_df %>%
select(사망자) %>%
slice(n()) %>% pull
valueBox(scales::comma(kor_death),
icon = "fa-skull",
color = "danger")
```
### 회복자수
```{r kor-recovered}
kor_recovered <- cv_kor_df %>%
select(회복자) %>%
slice(n()) %>% pull
valueBox(scales::comma(kor_recovered),
icon = "fa-walking",
color = "success")
```
Column {data-height=350}
-------------------------------------
### Chart 1
```{r kor-df}
cv_kor_df %>%
arrange(desc(일자)) %>%
DT::datatable(filter = 'top',
options = list( searchHighlight = TRUE, pageLength = 15,
dom = 'Bfrtip',
buttons = c('copy', 'csv', 'excel', 'pdf', 'print')),
extensions = 'Buttons') %>%
DT::formatRound(c("검사자", "확진자", "사망자", "회복자"), digits=0)
```
### Chart 2
```{r kor-df-viz}
korea_theme <- theme_classic(base_family = "NanumGothic") +
theme(legend.position = "none") +
theme(legend.background = element_rect(fill = "gainsboro")) +
theme(plot.background = element_rect(fill = "gainsboro")) +
theme(panel.background = element_rect(fill = "gainsboro"))
cv_kor_plot <- cv_kor_df %>%
gather(유형, 사람수, -일자) %>%
mutate(유형 = factor(유형, levels=c("검사자", "확진자", "회복자", "사망자"))) %>%
ggplot(aes(x=일자, y=사람수, color=유형)) +
geom_line() +
geom_point() +
facet_wrap(~유형, scale="fixed") +
scale_y_continuous(labels = scales::comma_format(scale = 1)) +
korea_theme +
labs(x="", y="") +
scale_color_viridis_d(option = "magma",
direction = -1)
plotly::ggplotly(cv_kor_plot)
```
정보
=======================================================================
**코로나19 대쉬보드 [^covid-vis]**
[^covid-vis]: [COVID-19 Maps & visuals](http://www.cidrap.umn.edu/covid-19/maps-visuals)
코로나19(covid-19) 관련 다양한 실시간 정보 및 현황을 다음 웹사이트를 통해서 얻을 수 있다.
- [코로나19 powered by `Tidyverse Korea`](https://statkclee.github.io/covid-19/)
- [코로나19(COVID-19): 실시간 상황판](https://wuhanvirus.kr/)
- [Coronavirus COVID-19 global cases (Johns Hopkins)](https://gisanddata.maps.arcgis.com/apps/opsdashboard/index.html#/bda7594740fd40299423467b48e9ecf6)
- [코로나바이러스감염증-19(COVID-19), 질병관리본부](http://ncov.mohw.go.kr/index_main.jsp)
**데이터**
- R 데이터 팩키지
- [`coronavirus`: The coronavirus dataset ](https://github.com/RamiKrispin/coronavirus)
- [`COVID-19`: Novel Coronavirus (COVID-19) Cases, provided by JHU CSSE](https://github.com/CSSEGISandData/COVID-19)
- [`covid`: Novel Coronavirus(2019-nCoV) updates from WHO daily reports](https://github.com/javierluraschi/covid)
- [PDF WHO 보고서](https://www.who.int/emergencies/diseases/novel-coronavirus-2019/situation-reports)
- 한국 데이터셋
- [박찬엽 구글 쉬트](https://drive.google.com/drive/folders/1_bjm76OE2H2xluT0D3hScUjvON9DpWXr)
- [질병관리본부, 코로나19 발생동향](http://ncov.mohw.go.kr/bdBoardList_Real.do?brdId=1&brdGubun=13&ncvContSeq&contSeq&board_id&gubun)
- [코로나19 일별 감염현황](https://docs.google.com/spreadsheets/d/1fODH5PZJw9jxwV2GRe85BRQgc3mxdyyIpQ0I6MDJKXc/edit#gid=0)
- [이성규, 미디어고토사](https://www.mediagotosa.com/korona19-hwagsan-ilbyeol-hyeonhwang-jeongri/)
**제작 방법과 배포**
- [`Tidyverse Korea`, 대쉬보드(Dashboard)](https://statkclee.github.io/comp_document/cd-dashboard.html)
- [`Tidyverse Korea`, `GitHub` 호스팅](https://statkclee.github.io/comp_document/cd-github-hosting.html)
**연락방법**
제작방법에 대해서 궁금하신 점이나 참여를 원하시는 분은 [issues](https://github.com/statkclee/covid-19/issues)에 남겨주시거나
[Tidyverse Korea 페북그룹](https://www.facebook.com/groups/tidyverse/)으로 연락주세요.