shiny tutorial 07 - flexdashboard package

Page content

공지

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

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

I. 이전 글 소개

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

II. flexdashboard 패키지의 개요

기존의 shinydashboard와의 가장 큰 차이점은 flexdashboard의 패키지는 R Markdown1 형식을 지원한다는 것이다.

  • 공식문서에 따르면, flexdashabord는 R에서 제공하는 다양한 형태의 htmlwidgets, base, lattice, grid graphics, tabular data, gauges and value boxes, and text annotations 등을 지원한다 (거의 대부분 기능을 제공한다는 뜻으로 읽힘).
  • 기존의 shiny tutorial를 잘 따라해왔다면, 대부분 느끼겠지만, 대시보드의 을 맞추는 건 쉽지가 않다. PC환경의 대시보드 형태로 구현이 되기 때문에, 모바일로 화면 전환이 쉽지가 않은데, flexdashboard는 이러한 기능도 제공한다.
  • 기본적으로 flexdashboard 패키지는 static한 대시보드인데, dynamic하게 앱을 작성할 수 있다.

III. Get Started

다른 R의 패키지처럼, flexdashboard 패키지를 설치한다.

install.packages("flexdashboard")

패키지를 설치하고 나면, [File] - [New File] - [R Markdown] - [From Template] 순서대로 클릭하면 아래와 같이 Flex Dashboard 파일이 활성화 되는데, 이 파일을 클릭한다.

클릭과 함께 아래와 같은 형태의 코드가 준비된 것을 확인할 수 있다.

```yaml
title: "Single Column (Scrolling)"
output: 
  flexdashboard::flex_dashboard:
    vertical_layout: scroll
```

여기에서 shiny dashboard 형태로 구현하려면 간단하게 runtime: shinyYAML header에 추가하면 된다.

```yaml
title: "Single Column (Scrolling)"
output: 
  flexdashboard::flex_dashboard:
    vertical_layout: scroll
runtime: shiny
```

(1) Sample

아래 샘플 소스코드를 작성하여 실행한다. 아래 소스 코드 실행의 주요 목적은 R MarkdownR Shiny가 어떻게 조금씩 다른지 확인하는 차원의 소스 코드이다. Sample 코드는 flexdashboard: Shiny Embedding 에서 가져와서 응용 했다.

---
title: "flexdashboard: Shiny Embedding"
output: 
  flexdashboard::flex_dashboard:
    vertical_layout: scroll
runtime: shiny
---

```{r global, include=FALSE}
# 데이터를 'global' chunk에 넣고, 대시보드의 모든 사용자가 데이터를 공유할 수 있도록 지원하는 소스 코드
library(datasets)
data(WorldPhones)
```

Module
=======================================================================

### Embedding a Shiny Module

```{r, include=FALSE}
# Shiny module definition (would typically be defined in a separate R script)

# UI function
worldPhonesUI <- function(id) {
  ns <- NS(id)
  fillCol(height = 600, flex = c(NA, 1), 
    inputPanel(
      selectInput(ns("region"), "Region:", choices = colnames(WorldPhones))
    ),
    plotOutput(ns("phonePlot"), height = "100%")
  )
}

# Server function
worldPhones <- function(input, output, session) {
  output$phonePlot <- renderPlot({
    barplot(WorldPhones[,input$region]*1000, 
            ylab = "Number of Telephones", xlab = "Year")
  })
}
```

```{r}
# Include the module
worldPhonesUI("phones")
callModule(worldPhones, "phones")
```

위 파일을 실행하면 아래와 같이 화면이 구성되면 완성이다.

기본적으로 flexdashabord의 구조는R Markdown의 목차 및 내용을 구성하는 방식과 비슷하다. 차이점이 있다면, R chunk {r, include=FALSE} 안에 shiny code를 진행할 수 있다는 장점이 있다.

본 소스코드에서는 Modularizing이 적용되었는데, 튜토리얼의 마지막 즈음에 복잡한 shiny app을 만들기 위한 가이드라인의 차원에서 다루도록 한다.2

이제 각각의 Layouts 대해 간단하게 설명하도록 해보자.

IV. Layouts

Layouts의 구성요소는 크게 3가지로 구분된다.

  • Orientation: 행과 열로 구분한다.
  • Scrolling Layout: 만약에 차트가 많다면 한 화면에 다 넣을 수 없기 때문에 이때에는 스크롤 기능을 추가해주는 것이 좋다.
  • Tabsets: 강사가 제일 좋아하는 기능이다. 이유는 간단한다. 다양한 그래프와 정보를 한 화면에서 볼 수 있도록 넣을 수 있고, Tab 클릭만으로 정보 제공이 가능하기 때문이다.

본 포스트에서는 Tabsets 기준으로 작성하였는데, 이 글을 보는 사람들도 가급적 아래와 같은 형식으로 기본 Format을 설정하는 것을 권유한다. 여기에서 주의해야 할 점은 어떤 시점에 {.tabset}을 코드 작성 하느냐에 따라 디자인이 달라지기 때문에 수시로 확인해서 점검한다.

There is no free lunch, Open Source is free but hardworking is required. - ChloEvan -

(1) Column

---
title: "name_of_your_project"
output: 
  flexdashboard::flex_dashboard:
    orientation: columns
    vertical_layout: fill
---

```{r setup, include=FALSE}
library(flexdashboard)
library(shiny)
```

---
title: "Tabset Column"
output: flexdashboard::flex_dashboard
---
    
Column 
-------------------------------------
    
### Chart 1
    
```{r}
h1('Chart 1')
```
   
Column {.tabset}
-------------------------------------
   
### Chart 2

```{r}
h1('Chart 2')
```   
 
### Chart 3
    
```{r}
h1('Chart 3')
```

실행된 화면에서 Chart 2Chart 3를 교대로 클릭하며 내용을 확인해본다. 이번에는 Rows를 기준으로 작업하는데, 사실상 달라지는 건 기존의 소스코드와 없다.

(2) Rows

---
title: "name_of_your_project"
output: 
  flexdashboard::flex_dashboard:
    orientation: rows
    vertical_layout: fill
---

```{r setup, include=FALSE}
library(flexdashboard)
library(shiny)
```

---
title: "Tabset Rows"
output: flexdashboard::flex_dashboard:
    orientation: rows
---
    
Row 
-------------------------------------
    
### Chart 1
    
```{r}
h1('Chart 1')
```
   
Row {.tabset .tabset-fade}
-------------------------------------
   
### Chart 2

```{r}
h1('Chart 2')
```   
 
### Chart 3
    
```{r}
h1('Chart 3')
```

{.tabset-fade} 속성값은 탭이 변환될 때마다 Fade in/out 효과를 적용하여 준다. 실제로 아래와 같이 나오는지 코드 작성을 통해 확인해본다.

V. Components

개요 페이지에서 언급했던 것처럼 flexdashboard는 다양한 Componets를 제공한다. shinyR Markdown 내용과 중복되는 예를 들면, R graphics, Tabular Data 등은 생략한다. 즉, 기존에 알고 있는 코드 문법과 차이가 없다는 뜻이기도 하다. 본 포스트에서는 HTML Widgets(사실, 이것도 shiny & shinydashboard에서도 사용은 가능하다!) Navigation Bar만 언급하도록 한다.

(1) HTML Widgets

CRAN에 등록되어 있는 30개 이상의 패키지는 HTML Widgets을 제공한다. 즉, 이러한 Widgets들은 모두 본 패키지에서 작성이 가능하다. 향후 코로나 프로젝트를 위해 지도 패키지인 leaflets의 간단 예제로 간단하게 소스 코드를 구현해본다. 소스코드보다는 어떻게 대시보드화가 되는지 결과 위주로 보기를 바란다.

---
title: "name_of_your_project"
output: 
  flexdashboard::flex_dashboard:
    orientation: rows
    vertical_layout: fill
---

```{r setup, include=FALSE}
library(flexdashboard)
library(shiny)
```

---
title: "Tabset Rows"
output: flexdashboard::flex_dashboard:
    orientation: rows
---
    
Row 
-------------------------------------
    
### Chart 1
    
```{r}
h1('Chart 1')
```
   
Row {.tabset .tabset-fade}
-------------------------------------
   
### Chart 2

```{r}
h1('Chart 2')

library(leaflet)
leaflet() %>%
  addTiles() %>%
  addMarkers(lng=174.768, lat=-36.852, popup="The birthplace of R")
```   

### Chart 3
    
```{r}
h1('Chart 3')
```

Chart 2 섹션에 지도화면이 정상적으로 출력된다면 완성이다. Chart 1에는 어떤 내용을 추가할지, Chart 3에는 어떤 내용을 추가할지 보여줘야 할지 고민해야 하며, Dynamic하게 모든 차트가 동시에 적용되게 하려면, 결국엔 데이터셋이 모듈화처럼 움직여야 한다 (일단, Pass!!, 본 프로젝트에 들어가면 자세히 소개하기로 한다!)

(2) Navigation Bar

Navigation Bar는 다중페이지가 만들어질 때 보통 사용된다. 대시 보드에 다중 페이지가 있으면 Navigation Bar의 왼쪽에 다중 페이지와 링크로 연결되게 되며, 이 때에는 소셜 링크와 대시 보드의 소스 코드를 볼 수 있다는 장점이 있다.

leaflet을 활용하여 만들었던 기존 소스코드에 Navigation Bar, social, source code 기능을 추가 하도록 하겠다. 어디에 어떻게 구현이 되는지 확인해보자.

---
title: "name_of_your_project"
output: 
  flexdashboard::flex_dashboard:
    orientation: rows
    vertical_layout: fill
    navbar:
      - { title: "About", href: "https://chloevan.github.io/about/" }
    social: [ "twitter", "facebook", "menu", "linkedin" ]
    source_code: embed
---

```{r setup, include=FALSE}
library(flexdashboard)
library(shiny)
```

---
title: "Tabset Rows"
output: flexdashboard::flex_dashboard:
    orientation: rows
---
    
Row 
-------------------------------------
    
### Chart 1
    
```{r}
h1('Chart 1')
```
   
Row {.tabset .tabset-fade}
-------------------------------------
   
### Chart 2

```{r}
h1('Chart 2')

library(leaflet)
leaflet() %>%
  addTiles() %>%
  addMarkers(lng=174.768, lat=-36.852, popup="The birthplace of R")
```   

### Chart 3
    
```{r}
h1('Chart 3')
```

우측 상단에 보면, About 버튼, 각각의 Social Network 기능, 특히 Facebook, Twitter, Linkedin과 같이 대시보드를 공유할 수 있는 기능들이 있는 것을 볼 수 있다. 이러한 기능들은 현재 Corona-19 대시보드와 같이 빅데이터를 활용하여 시각화로 Insight를 줄 때, 매우 유용한 기능이다.

마지막으로 source code는 현재 보고 있는 화면에 대한 전체 source code를 보여주는 기능인데, 이 부분 역시 소스코드 공유를 통해 커뮤니티에 기여하고 싶을 때 넣어주면 좋다.

VII. shinydashboard Vs. flexdashboard의 활용에 관한 개인적인 단상

각 패키지마다 장단점이 있지만, 굳이 두가지 중에서 한 패키지를 먼저 배워야 한다면 강사는 flexdashboard로 우선 작업하는 것을 권유한다.

먼저, shinydashboard Vs. flexdashboard에 대한 비교 글에 대한 원문을 읽어보는 것을 권한다. (사실 그렇게 큰 내용은 없다.)

일단 간단하게 요약하면, shinydashboard는 입문자들이 접근하기에는 조금 어려운 점이 있다. 물론, 추후에 HTML & CSS와 같은 기능에 대한 필요성이 느껴진다면, shinydashboard에 자바스크립트 등 복잡성 있게 구현이 가능하겠지만.. 추천하지는 않는다 (왜 꼭 R로 그렇게 해야하는가? 복잡성 있게 구현한다면 나는 차라리 유료 BI Tool을 쓰자고 할 것 같다!) 하는 의문점이 늘 있어왔다. 다년간 R 커뮤니티를 관찰한 결과 R을 활용하는 사람들의 대부분(특히 국내 R 유저의 특성상)의 사실상 프로그래밍에 익숙하지 않은 사람들이 대부분인 것을 추정하기 때문에 R Shiny를 하는 사람들에게 R Markdown 보고서를 빠르게 웹으로 구현하는 일련의 과정이 훨씬 빠르고 간결하기 때문에 추천한다. (지극히 개인적인 생각)

VIII. 다루지 못한 것들

shinydashboardflexdashboard에 다양한 기능들을 접해봤지만, 아직 다루지 못한 그러나 중요한 기능이 하나 있다. Mobile의 접근성이다. 이 부분은 향후 프로젝트를 진행하면서 한번 짚고 넘어가도록 하겠다.

이제 기본적인 이론 중 마지막 한가지가 남아있다. shiny에서 HTML, CSS, 그리고 Javascript 연동이다.

이제 미니 프로젝트의 시작점이 얼마 남지 않았다. 고지를 향해 조금만 더 달려가보자!

IX. Reference

flexdashboard, (2020). flexdashboard Retrieved April 2, 2020, from https://rmarkdown.rstudio.com/flexdashboard/index.html

Congratulation! You Mastered flexdashboard in Shiny


  1. ChloEvan. (2020, March 18). R Markdown Introduction. Retrieved April 2, 2020, from https://chloevan.github.io/r/rmarkdown/rmarkdownintro/ ↩︎

  2. 웹개발 개발경력이 되신 분들은 shiny 홈페이지에 게재된 Modularizing Shiny app code을 자세히 읽어보기를 권한다. ↩︎