공지

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

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

I. 이전 글 소개

처음 shiny를 접하거나 shiny의 전체 튜토리얼이 궁금한 사람들을 위해 이전 글을 소개한다. - shiny tutorial 01 - get started - shiny tutorial 02 - Shiny Structure - shiny tutorial 03 - HTML content - shiny tutorial 04 - Shiny Layouts - shiny tutorial 05 - Sharing Apps

II. shinydashboard 패키지의 개요

HTML contentLayouts 조작하는 것이 편해지면 대시보드를 만들 수 있다. 그런데, 문제는 대시보드 개발을 처음부터 하는 것과 어느정도 정해진 포맷을 활용하여 작성하는 것은 다르다. 반복해서 말하지만, 데이터분석가가 처음부터 개발해서 사내 내부용 보고서를 꼭 작성해서 만들어야 하는가?하는가? 글쎄. 개인적으로 동의하기 어렵다. 핵심적인 내용의 지표만 산출 및 작성 요약하여 보고하는 것이 데이터 분석가의 기본적인 업무이자 핵심적인 업무이기 때문에, 다양한 대시보드를 빠르게 그러나 가독성있게 만드는 것이 중요하다. 어차피, 이러한 대시보드 역시, 시간이 지나면 결국엔 보는 사람만 본다.

shinydashboard 패키지와 그리고 다음 장에서 설명할 flexdashboard 패키지를 활용하여 대시보드를 빠르게 만들어봄으로써 shiny 개발 & 배포를 빠르게 반복적으로 진행하며 학습하는 것을 권한다.

III. Get Started

다른 R의 패키지처럼, shinydashboard 패키지를 설치한다. shiny 패키지가 설치가 되어 있지 않거나 shiny Version (>=0.11)이 낮은 경우, 설치 에러가 날 수 있으니 주의 한다.

install.packages("shinydashboard")

(1) shinydashboard 구조

Shiny의 기본구조는 ui, server, shinyApp으로 구성되어 있음을 알고 있다. shinydashboard 패키지를 사용시, 이 때의 ui 문법이 조금 달라진다. 어렵지는 않다. 그냥 제공하는 함수가 다를 뿐이다.

일단 간단하게 소스와 결과를 확인해 보자! 아래 소스코드를 따라하면서 연습할 때는 app.R 파일을 생성한 뒤 아래 코드를 작성하도록 한다.

library(shiny)
library(shinydashboard)
## 
## Attaching package: 'shinydashboard'
## The following object is masked from 'package:graphics':
## 
##     box
ui <- dashboardPage(
  dashboardHeader(),
  dashboardSidebar(),
  dashboardBody()
)

server <- function(input, output) { }

shinyApp(ui, server)
## 
## Listening on http://127.0.0.1:3474

dashboardPage() 안에 Header(), Sidebar(), Body()가 만들어진다.

위 대시보드는 default로 만들어진 것이고, 여기에서 이제 각각의 구성품을 채워넣는 작업을 할 것이다.

IV. Basic Dashboard

(1) dashboardHeader()

먼저 제목부터 달아보자.

library(shiny)
library(shinydashboard)

ui <- dashboardPage(
  dashboardHeader(title = "첫번째 대시보드"),
  dashboardSidebar(),
  dashboardBody()
)

server <- function(input, output) { }

shinyApp(ui, server)
## 
## Listening on http://127.0.0.1:4095

왼쪽 상단에 첫번째 대시보드 글자가 보일 것이다. 만약, dashboardHeader(disable = TRUE)를 하게 되면 불필요해 보이는 header 공간은 사라지고 SidebarBody 공간만 남게 된다.

(2) dashboardSidebar()

Sidebar의 주 활용 용도는 메뉴 구성과 같은 개념으로 파악하면 좋다. 아래 소스코드를 활용해서 실습하기를 바란다.

library(shiny)
library(shinydashboard)

ui <- dashboardPage(
  dashboardHeader(title = "첫번째 대시보드"),
  dashboardSidebar(
    # 사이드바 메뉴 구성
    sidebarMenu(
      menuItem(text = "대시보드", tabName = "dashboard", icon = icon("dashboard")),
      menuItem(text = "위젯", tabName = "widgets", icon = icon("th"))
    )
  ),
  dashboardBody()
)

server <- function(input, output) { }

shinyApp(ui, server)
## 
## Listening on http://127.0.0.1:7315

dashboardSidebar() 안에 sidebarMenu() 메뉴 구성을 만든다. 그 이후에 menuItem()을 입력하는데, 다양한 Arguments들이 있는 것을 확인할 수 있다. 각 Arguments 사용 설명서는 ?menuItem를 실행한 후, 확인하는 것을 추천한다. 각각의 Arguments들은 일종의 대시보드 화면을 좀 더 Interactive하게 만들어주는 옵션이기 때문에, 다양한 방법으로 시도하는 것을 권유한다.

(3) dashboardBody()

기존 shiny에서 작업했던 inputId, outputId 값이 일치한 것을 기억했으면 좋겠다. 마찬가지로 menuItem() tabName값은 Body() tabName값과 일치해야 한다.

이유는 간단하다. menuItem의 각 메뉴들을 클릭할 때마다, 다른 화면이 나타나게끔 하려고 하는 것이 menuItem을 사용하는 목적이기 때문이다. 일종의 Key값이라고 하면 적정한 표현일까?

아래 소스를 통해서 한번 더 확인해본다. Body 안에 들어가는 소스코드도 중요하지만, 여기에서는 tabName을 유심히 관찰할 필요가 있다. 처음에 발생하는 에러의 대부분은 ID가 일치하지 않아 발생하는 경우가 대부분이다.

library(shiny)
library(shinydashboard)

ui <- dashboardPage(
  dashboardHeader(title = "첫번째 대시보드"),
  dashboardSidebar(
    # 사이드바 메뉴 구성
    sidebarMenu(
      menuItem(text = "대시보드", tabName = "dashboard", icon = icon("dashboard")),
      menuItem(text = "위젯", tabName = "widgets", icon = icon("th"))
    ) # sidebarMenu
  ), # dashboardSidebar
  dashboardBody(
    tabItems(
      # First tab content
      tabItem(tabName = "dashboard",
        h2("대시보드 탭 내용"), 
        fluidRow(
          box(plotOutput("plot1", height = 250)),

          box(
            title = "Controls",
            sliderInput("slider", "Number of observations:", 1, 100, 50)
          ) # box
        ) # fluidRow
      ), # tabItem(tabName = "dashboard")

      # Second tab content
      tabItem(tabName = "widgets",
        h2("위젯 탭 내용")
      ) # tabItem
    ) # tabItems
  ) # dashboardBody
)

server <- function(input, output) { 
  set.seed(122)
  histdata <- rnorm(500)

  output$plot1 <- renderPlot({
    data <- histdata[seq_len(input$slider)]
    hist(data)
  })
}

shinyApp(ui, server)
## 
## Listening on http://127.0.0.1:8129

dashboardBody()tabItemstabItem 순서대로 코드를 작성하는데, 가장 많이 실수하는 곳은 예상할 수 있겠지만 tabItemstabItem 오기하는 것이 많기 때문에 주의 하기 바란다.

아래 그림은 대시보드 탭을 클릭했을 때 나타나는 화면이다.

아래 그림은 위젯 탭을 클릭했을 때 나타나는 화면이다.

V. 더 알아보기

지금까지 작성한 내용은 매우 기초적인 부분에서만 접근을 한 것이기 때문에, 더 많은 기능은 직접 해봐야 알 수 있다. shinydashboard 패키지에 대한 구체적인 내용들은 Structure, Apperance 등을 참조하기를 바란다.

VI. Sample

shinydashboard를 활용한 예제코드를 보면서 필사 하는 것을 추천한다. 그리고 전반적인 과정을 이해하면, 그 후에 약간의 코드 수정으로 응용하여 배포하는 것을 권유한다.

VI. Reference

shinydashboard., (2020). shinydashboard. Retrieved April 1, 2020, from https://rstudio.github.io/shinydashboard/index.html/

Congratulation! You Mastered Deployment in Shiny