Corona Shiny Project 2 - Visusalization (Time Series)

Page content

공지

이번에 준비한 튜토리얼은 제 강의를 듣는 과거-현재-미래 수강생분들을 위해 준비한 자료이다. 많은 도움이 되기를 바란다

이번에 준비한 Tutorial 코로나 세계현황을 Shiny Dashboard로 만들어 가는 과정을 담았다.

I. Shiny Tutorial 소개

처음 shiny를 접하거나 shiny의 전체 튜토리얼이 궁금한 사람들을 위해 이전 글을 소개한다.

II. Shiny Project

이전 포스트에서는 Corona 데이터셋을 구하는 방법에 대해 기술하였다. 그리고, 데이터셋을 MongoDB에 저장하는 방법에 대해 서술하였다.

III. Shiny Project with flexdashboard package.

강사는 flexdashboard 패키지를 활용할 예정이기 때문에 어떻게 처음 시작하는지는 여기서 추가 설명은 하지 않는다. 다만, 처음 이 페이지를 방문한 사람을 위해 강사가 작성한 블로그 글 shiny tutorial 07 - flexdashboard에서 참조하기를 바란다.

(1) Model Dashboard

강사가 참조하려는 대시보드는 아래와 같이 만들어갈 예정이다. Heatmap 대신에 세계지도를 넣으려고 하며, 날짜에 따라 어떻게 시시각각 변하는지 만들 예정이다. 또한, Time Series Chart 또는 Bubble Chart 애니메이션을 활용하여 국가별로 누적 확진자수와 사망자수를 만들 예정이다.

(2) 필수 패키지 불러오기

강사가 사용하려는 패키지는 아래와 같다. (작업하다보면 추가가 될 수 있어서, 계속 업데이트 하려고 한다.)

```r
# 데이터를 'global' chunk에 넣고, 대시보드의 모든 사용자가 데이터를 공유할 수 있도록 지원하는 소스 코드

library(shiny)
library(mongolite)
library(tidyverse)
library(leaflet)
library(dygraphs)
library(xts)
```

(3) Layout 기본 구성

강사는 아래와 같이 기본 구성도를 작성하였다.

III. Get Data From MongoDB

아래 소스코드를 통해서 데이터를 가져온다. 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에 작성한다. 이유는 위 데이터를 우선 공동으로 사용되어야 하기 때문이다.

  • Tip-1: 여기에서 Sys.getenv("MONGO_ID")와 함께 App Publishing을 진행하면, shinyapp.io에서 에러가 날 가능성이 크다. 이유는 Sys.getenv("")은 환경설정 파일(.Renviron)인데, 당연히 github 등에는 공적으로 같이 올리지 않는다. 강사는 publishing 할 때, 명시적으로 ID와 PW를 같이 기재하여 배포하였지만, 보안상으로는 당연히 그렇게 하면 안된다. 이에 대한 적절한 해결책을 공유하니, 참고하기를 바란다.

IV. Sidebar 구성

이제 본격적으로 시각화를 구현하기에 앞서서 슬라이드형 날짜를 구성해보자.

(1) 전역변수 지정

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
  })
```

추가적으로 더 넣을 내용이 생기면 업데이트 하겠다.

V. Time Series 데이터 작성

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 패키지 설명서를 다시 한번 읽어보자.

이런 형태로 소스코드를 응용할 것이다. 잘 따라와주기를 바란다.

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와 연동하려면, 보다 더 많은 작업을 해야 한다! 아직은 좀 더 기다리자.

다음 시간에는 Bubble Chart를 작성하는 코드를 실습해보자.

Pray for Victims of Covid_19. Contribution to them with this tutorial.