이번에 준비한 튜토리얼은 제 강의를 듣는 과거-현재-미래 수강생분들을 위해 준비한 자료이다. 많은 도움이 되기를 바란다
이번에 준비한 Tutorial 코로나 세계현황을 Shiny Dashboard
로 만들어 가는 과정을 담았다.
처음 shiny를 접하거나 shiny의 전체 튜토리얼이 궁금한 사람들을 위해 이전 글을 소개한다.
이전 포스트에서는 Corona 데이터셋
을 구하는 방법에 대해 기술하였다. 그리고, 데이터셋을 MongoDB
에 저장하는 방법에 대해 서술하였다.
강사는 flexdashboard
패키지를 활용할 예정이기 때문에 어떻게 처음 시작하는지는 여기서 추가 설명은 하지 않는다. 다만, 처음 이 페이지를 방문한 사람을 위해 강사가 작성한 블로그 글 shiny tutorial 07 - flexdashboard에서 참조하기를 바란다.
강사가 참조하려는 대시보드는 아래와 같이 만들어갈 예정이다. Heatmap
대신에 세계지도를 넣으려고 하며, 날짜에 따라 어떻게 시시각각 변하는지 만들 예정이다. 또한, Bubble Chart
애니메이션을 활용하여 국가별로 누적 확진자수와 사망자수를 만들 예정이다.
강사가 사용하려는 패키지는 아래와 같다. (작업하다보면 추가가 될 수 있어서, 계속 업데이트 하려고 한다.)
```r
# 데이터를 'global' chunk에 넣고, 대시보드의 모든 사용자가 데이터를 공유할 수 있도록 지원하는 소스 코드
library(shiny)
library(mongolite)
library(tidyverse)
library(leaflet)
library(dygraphs)
library(xts)
```
강사는 아래와 같이 기본 구성도를 작성하였다.
아래 소스코드를 통해서 데이터를 가져온다. MongoDB에 관련된 자료는 R MongoDB 접속 및 소개 자료에서 확인하기를 바란다. 사실 본 프로젝트에서는 꼭 이렇게 하지 않아도 된다. 그러나, 조금 더 깊은 내용을 원하면, 이렇게 해줘야 함을 명시한다.
library(mongolite)
collection <- "covid_19"
db <- 'learningspoons'
mongo_id <- Sys.getenv("MONGO_ID") # 보안 유지를 위해 가렸다.(실무에서는 이렇게 작업하라고 권유하는 것임!)
mongo_pw <- Sys.getenv("MONGO_PW") # (실무에서는 이렇게 작업하라고 권유하는 것임!)
mongo_url <- paste0('mongodb+srv://', mongo_id, ':',mongo_pw,'@learningspoons-rhpei.gcp.mongodb.net/')
conn <- mongo(collection = collection,
db = db,
url = mongo_url)
# get data
corona <- conn$find("{}")
위 소스코드는 global
chunk에 작성한다. 이유는 위 데이터를 우선 공동으로 사용되어야 하기 때문이다.
Sys.getenv("MONGO_ID")
와 함께 App Publishing
을 진행하면, shinyapp.io에서 에러가 날 가능성이 크다. 이유는 Sys.getenv("")
은 환경설정 파일(.Renviron
)인데, 당연히 github
등에는 공적으로 같이 올리지 않는다. 강사는 publishing 할 때, 명시적으로 ID와 PW를 같이 기재하여 배포하였지만, 보안상으로는 당연히 그렇게 하면 안된다. 이에 대한 적절한 해결책을 공유하니, 참고하기를 바란다.
global chunk
에 아래와 같이 추가적으로 코드를 입력한다.
# 날짜 지정
corona_date <- as.Date(corona$dateRep)
# 특정 Input값이 없을 경우 대비
variable <- F
위 코드를 지정했다면, 아래와 같이 소스코드를 작업한 뒤 결과물을 빠르게 확인한다.
Inputs {.sidebar data-width=300}
-----------------------------------------------------------------------
원하는 날짜에 놓고 `Button`을 누르세요.
```r
uiOutput("Slider")
sliderInput("day1", "Day", min(corona_date), max(corona_date),
value = c(max(corona_date)), animate = T, step = 1)
renderUI({
if(is.null(input$variable)){
}else{
if(input$variable %in% c("cases", "deaths")){
sliderInput("day1", "Day", min(corona_date), max(corona_date),
value = c(max(corona_date)), animate = T, step = 1)
}else{
sliderInput("day2", "Day", min(corona_date), max(corona_date),
value = c(max(corona_date)-7,max(corona_date)), animate = T, step = 1)
} # else
} # is.null
})
```
추가적으로 더 넣을 내용이 생기면 업데이트 하겠다.
Shiny App
을 작성할 때, 특히 시각화와 데이터 처리와 관련해서 작업할 때는 R Markdown
에서 하는 것보다, 일반 .R
파일을 하나 생성해서 빠르게 구현하는 것을 추천한다.
강사가 작업할 Time Series 시각화는 dygraphs
패키지를 할용하려고 한다. 참고로 강사 역시, dygraphs 패키지를 이전에 사용해본적은 없다! 즉, 현재 듣는 수강생과 동일한 입장에서 작업하는 것임을 알고, 자신감 있게 작업하기를 바란다.
강사가 R 에디터에서 빠르게 작업한 전체 소스코드는 아래와 같다.
# load data in 'global' chunk so it can be shared by all users of the dashboard
library(mongolite)
library(tidyverse)
library(dygraphs)
library(xts)
collection <- "covid_19"
db <- 'learningspoons'
mongo_id <- Sys.getenv("MONGO_ID") # 보안 유지를 위해 가렸다.(실무에서는 이렇게 작업하라고 권유하는 것임!)
mongo_pw <- Sys.getenv("MONGO_PW") # (실무에서는 이렇게 작업하라고 권유하는 것임!)
mongo_url <- paste0('mongodb+srv://', mongo_id, ':',mongo_pw,'@learningspoons-rhpei.gcp.mongodb.net/')
conn <- mongo(collection = collection,
db = db,
url = mongo_url)
# get data
corona <- conn$find("{}")
# 날짜 변환
corona$dateRep <- as.Date(corona$dateRep)
# summarise
corona2 <- corona %>%
group_by(dateRep) %>%
summarise(total_cases = sum(cases),
total_deaths = sum(deaths))
cases_data <- xts(x = corona2[, -1], order.by = corona2$dateRep)
p <- dygraph(cases_data) %>%
dyOptions(drawPoints = TRUE, pointSize = 4, fillGraph=TRUE)
p
이제 R Markdown
에 응용만 하면 된다. 그런데, 여기서 주의점! shiny tutorial
에서 패키지 설명서를 잘 읽었다면, interactive graph package와 연동이 잘 된다는 걸 기억했으면 좋겠다. 즉, 생각보다 쉽게 작업할 수 있다는 뜻이다. dygraphs
패키지 설명서를 다시 한번 읽어보자. - Using in Shiny Applications - ui.R
코드에서 dygraphOutput("dygraph")
을 봤으면 좋겠다.
이런 형태로 소스코드를 응용할 것이다. 잘 따라와주기를 바란다.
corona_xts <- reactive({
temp <- corona %>%
mutate(dateRep = as.Date(dateRep)) %>%
group_by(dateRep) %>%
summarise(total_cases = sum(cases),
total_deaths = sum(deaths))
xts::xts(x = temp[, -1], order.by = temp$dateRep)
})
renderDygraph({
dygraph(corona_xts(), height = 400) %>%
dyHighlight(highlightCircleSize = 5,
highlightSeriesBackgroundAlpha = 0.2,
hideOnMouseOut = FALSE) %>%
dyOptions(drawPoints = TRUE,
pointSize = 4,
fillGraph=TRUE,
axisLineWidth = 1.5)
})
위와 같은 형태로 나오면 완성이다. 아쉽지만, 아직은 date
와 연동된 것은 아니다. date
와 연동하려면, 보다 더 많은 작업을 해야 한다!
다음 시간에는 date
에 따라 애니메이션 처럼 움직이는 그래프를 만들어본다!
Pray for those who are victimized by Covid_19. Contribution to them with this tutorial.