기본 콘텐츠로 건너뛰기

5.1.1 R Flexdashboard를 통해 Dashboard 만들기 1편

Ch3. Flexdashboard를 통한 Dashboard 만들기 1편

Ch3. Flexdashboard를 통한 Dashboard 만들기 1편

  1. Dashboard 만드는 순서

    • 출력 옵션 설정

      • 대시보드 제목
      • 페이지 제목
      • 소스코드 삽입 여부
      • 레이아웃 배치 기준 설정(행 기준 혹은 열 기준)
      • 출력형식 설정
    • 대시보드 레이아웃 구성

      • 사이드바 삽입 여부
      • Row 혹은 Column 을 추가함으로써 레이아웃 추가
    • 그래프 추가

      • 사이드바 혹은 배치된 Row & Column 배치 코드 밑에 그래프 추가
    • Rendor plot 및 plotly 추가 여부

      • Rendor plot이란 대시보드에 직접 input parameter를 추가함으로써, input의 변경 여부에 따라 그래프가 변경되는 동적 대시보드를 만들고자 할 때 쓰이는 plot입니다.
      • plotly는 그래프를 확대해서 볼 수도 있고, 마우스를 그래프에 위치시키면 그래프의 값이 나오게 되는 패키지입니다.
  2. 참고 사이트 : https://rmarkdown.rstudio.com/flexdashboard/using.html

    제가 사진으로 업로딩한 Dashboard 코드는 다음과 같습니다. 전체적인 구조를 한번 훑어보고 하나씩 따로 이해하는 것으로 진행하겠습니다.

    참고로 이제부터 시작하는 코드들은 모두 markdown 문법형태입니다.

     

  3. Dashboard 출력 옵션 적용
  4. ---
    title: "LEARNIT"  <!-- Dashboard 이름 설정 -->
    output: 
      flexdashboard::flex_dashboard:
        orientation: rows <!-- layout 배치를 행(row)이 늘어나는 식으로  배치 -->
        source_code: embed <!-- Source code 삽입 --> 
        theme: readable
      runtime: shiny
    ---
    
  5. 시각화에 필요한 패키지 및 데이터 및 전처리 작업 진행
  6. 데이터 다운로드 링크 : https://www.kaggle.com/PromptCloudHQ/imdb-data

    대시보드를 구성하기 전에, 필요한 전처리는 미리 다 작업을 한 후에, 대시보드 작성을 시작합니다.

    ```{r setup, include=FALSE} <!-- include = FALSE 옵션, 해당되는 R code는 표시되지 않음 -->
    library(flexdashboard)
    library(ggplot2)
    library(plotly)
    library(shiny)
    library(plyr)
    library(dplyr)
    library(plotly)
    library(tm)
    ```
    
    ```{r}
    DATA = read.csv("C:/R/IMDB-Movie-Data.csv")
    ```
    
    ```{r}
    DATA$Genre2 = DATA$Genre
    
    DATA$Genre2=gsub(","," ",DATA$Genre2)
    
    CORPUS=Corpus(VectorSource(DATA$Genre2))
    CORPUS_TM = tm_map(CORPUS,removePunctuation)
    CORPUS_TM = tm_map(CORPUS_TM, removeNumbers)
    CORPUS_TM = tm_map(CORPUS_TM, tolower)
    
    DTM = DocumentTermMatrix(CORPUS_TM)
    
    DTM = as.data.frame(as.matrix(DTM))
    
    DATA = cbind(DATA,DTM)
    
    FIRST_GENRE = c()
    for(i in 1:nrow(DATA)){
      FIRST_GENRE[i] = strsplit(as.character(DATA$Genre[i]),",")[[1]][1]
    }
    
    DATA$FIRST_GENRE = FIRST_GENRE
    ```
    
  7. Dashboard 페이지 이름 및 아이콘 설정(윗단 구성 완료)
  8. DASHBOARD CREATING {data-icon="fa-signal"} <!-- Dashboard 이름 설정 및 아이콘 설정 -->
    ========================== <!-- = 으로 분리하면 격자선이 생기면서 윗단 구성을 완료 -->
    
  9. Dashboard 레이아웃 구성
    • 전체 레이아웃
    • 1번 레이아웃 배치 코드 (사이드바)
    Column {.sidebar}  <!--1번 레이아웃 설정 코드-->
    --------------------------
    
    Today : 2018-12-04 TUE    
    Learnit Job Class    
    Description :    
    
    1. 대시보드 만들기      
    2. 새로운 평가지표 만들어보기    
    3. 그래프 이쁘게 그려보기    
    4. 유지보수 잘하기    
    
    ```{r}
    selectInput('Genre', 'Genre',DATA$FIRST_GENRE,
                selected = 'action')
    
    numericInput("Rating", "min Rating:", 6)
        
    ```
    

    레이아웃을 배치할 때는 항상 Column 혹은 Row를 써준 다음에 '-------------------'를 써서 구분지어주면 바로 배치가 완성이 됩니다.

    • 2번 레이아웃 배치 코드

    일반적인 layout 배치도 다음과 같습니다 . Row를 선언해주고 '-------------------'를 써서 구분지어주면 배치는 완료됩니다. 그 밑에는 제목을 적어주고 컨텐츠를 작성해주면 됩니다.

    Row {data-height=100} <!-- Row 를 선언해줌으로써 2번 레이아웃 배치 선선 -->
    ------------------------ <!-- 2번 레이아웃 배치코드 구분선 -->
    ### Target Of Dashboard <!-- 레이아웃 제목 정해주기 -->
    
    parameter 설정에 따라 변경되는 동적 대시보드 만들기
    
    • 3번 레이아웃 배치코드

    3번 레이아웃은 다음의 코드로 만들어 집니다. 내부 valueBox라던지, selectedData같은 명령어는 후에 정리하도록 하겠습니다.

    Row <!-- 3번 레이아웃 배치코드 -->
    -------------------------------- <!-- 3번 레이아웃 배치코드 구분선 -->
    
    <!-- 레이아웃 제목을 추가한만큼 레이아웃이 제목 수만큼 분할하고 컨텐츠를 보여줌 -->
    <!-- 추가하는 레이아웃은 좌측부터 우측으로 순서대로 배치 -->
    
    ### Total Movies <!-- 3번 레이아웃 좌측 컨텐츠 제목 작성 -->
    
    <!-- 컨텐츠 작성 -->
    ```{r}
    valueBox(value = paste(nrow(DATA),"movies"),
             color='royalblue')
    ```
    
    ### Selected Movies <!-- 3번 레이아웃 중앙 컨텐츠 제목 작성 -->
    
    <!-- 컨텐츠 작성 -->
    ```{r}
    selectedData = reactive({
      subset(DATA,FIRST_GENRE==input$Genre)
    })
    ```
    
    ```{r}
    
    renderValueBox({
      valueBox(
        value = nrow(selectedData()),
        icon = "fa-area-chart",
        color = ifelse(nrow(selectedData()) < 50, "warning", "primary")
      )
    })
    
    ```
    
    ### Ratings Gauge <!-- 3번 레이아웃 우측 컨텐츠 제목 작성 -->
    
    ```{r}
    
    renderGauge({
      gauge(round(mean(selectedData()$Metascore,na.rm = TRUE),2), 
            min = 0, max = 100, 
          gaugeSectors(
      success = c(80, 100), warning = c(40, 79), danger = c(0, 39)
    ))
    })
    
    ```
    
    • 4번 레이아웃 배치코드
    Row {data-width=650}  <!-- 4번 레이아웃 배치코드 -->
    ------------------------ 
    ### 년도별 영화 매출 추이(전체) <!-- 4번 레이아웃 좌측 그래프 제목 -->
    
    <!-- 4번 레이아웃 좌측 그래프 코드 -->
    ```{r}
    
     YEAR1 = DATA %>%
      group_by(Year) %>%
      dplyr::summarise(MEAN = mean(Revenue..Millions.,na.rm = TRUE),
                       MEDIAN = median(Revenue..Millions.,na.rm = TRUE))
     p = ggplot(YEAR1) +
      geom_line(aes(x=Year,y=MEAN),group = 1 , col ='red') +
      geom_point(aes(x=Year,y=MEAN), col ='red') +
      geom_line(aes(x=Year,y=MEDIAN),group = 1 , col = 'royalblue') +
      geom_point(aes(x=Year,y=MEDIAN) , col = 'royalblue') +
      xlab("년도") + ylab("매출액") 
     
     ggplotly(p)
     
    ```
    
    ### 년도별 영화 매출 추이(장르 선택) <!-- 4번 레이아웃 우측 그래프 제목 -->
    
    <!-- 4번 레이아웃 우측 그래프 코드 -->
    ```{r}
    
    renderPlotly({
     YEAR2 = selectedData() %>%
      group_by(Year) %>%
      dplyr::summarise(MEAN = mean(Revenue..Millions.,na.rm = TRUE),
                       MEDIAN = median(Revenue..Millions.,na.rm = TRUE))
     p = ggplot(YEAR2) +
      geom_line(aes(x=Year,y=MEAN),group = 1 , col ='red') +
      geom_point(aes(x=Year,y=MEAN), col ='red') +
      geom_line(aes(x=Year,y=MEDIAN),group = 1 , col = 'royalblue') +
      geom_point(aes(x=Year,y=MEDIAN) , col = 'royalblue') +
      xlab("년도") + ylab("매출액") 
     
     ggplotly(p)
    })
    
    ```
    
    • 5번 레이아웃 코드
    Row {data-width=650} <!-- 5번 레이아웃 배치코드 -->
    ------------------------ 
    ### 데이터 테이블 <!-- 5번 레이아웃 테이블 제목 설정 -->
    
    ```{r}
    selectedData2 = reactive({
      subset(DATA,FIRST_GENRE==input$Genre & Rating > input$Rating)
    })
    ```
    
    ```{r}
    renderTable({
     DF = selectedData2()[,c(2,3,5:10,34)]
     DF[order(-DF$Rating),]
    })
    
    ```
    

    여기까지 대시보드 작성 코드였습니다. 대략적인 구조는 이해가 되셨나요? 어려워 보이지만 구조를 파악하면 어려울 것이 없습니다. 출력옵션을 정해주고, 레이아웃 배치를 간단하게 정한다음 그래프를 넣어주면 끝나는 겁니다.

    다음으로 예시 레이아웃 예시본을 보여드리면서 레이아웃 구성은 마무리 짓도록 하겠습니다.

    전체코드는 다음과 같습니다.

    ---
    title: "LEARNIT"
    output: 
      flexdashboard::flex_dashboard:
        orientation: rows
        source_code: embed
        theme: readable
      runtime: shiny
    ---
    
    ```{r setup, include=FALSE}
    library(flexdashboard)
    library(ggplot2)
    library(plotly)
    library(shiny)
    library(plyr)
    library(dplyr)
    library(plotly)
    library(tm)
    ```
    
    ```{r}
    DATA = read.csv("C:/R/IMDB-Movie-Data.csv")
    ```
    
    ```{r}
    DATA$Genre2 = DATA$Genre
    
    DATA$Genre2=gsub(","," ",DATA$Genre2)
    
    CORPUS=Corpus(VectorSource(DATA$Genre2))
    CORPUS_TM = tm_map(CORPUS,removePunctuation)
    CORPUS_TM = tm_map(CORPUS_TM, removeNumbers)
    CORPUS_TM = tm_map(CORPUS_TM, tolower)
    
    DTM = DocumentTermMatrix(CORPUS_TM)
    
    DTM = as.data.frame(as.matrix(DTM))
    
    DATA = cbind(DATA,DTM)
    
    FIRST_GENRE = c()
    for(i in 1:nrow(DATA)){
      FIRST_GENRE[i] = strsplit(as.character(DATA$Genre[i]),",")[[1]][1]
    }
    
    DATA$FIRST_GENRE = FIRST_GENRE
    ```
    
    
    DASHBOARD CREATING {data-icon="fa-signal"}
    ==========================
    Column {.sidebar}
    --------------------------
    Today : 2018-12-04 TUE    
    Learnit Job Class    
    Description :    
    
    1. 대시보드 만들기      
    2. 새로운 평가지표 만들어보기    
    3. 그래프 이쁘게 그려보기    
    4. 유지보수 잘하기    
    
    ```{r}
    selectInput('Genre', 'Genre',DATA$FIRST_GENRE,
                selected = 'action')
    
    numericInput("Rating", "min Rating:", 6)
        
    ```
    
    Row {data-height=100}
    ------------------------
    ### Target Of Dashboard
    
    parameter 설정에 따라 변경되는 동적 대시보드 만들기
    
    Row
    --------------------------------
    ### Total Movies
    
    ```{r}
    valueBox(value = paste(nrow(DATA),"movies"),
             color='royalblue')
    ```
    
    ### Selected Movies
    ```{r}
    
    selectedData = reactive({
      subset(DATA,FIRST_GENRE==input$Genre)
    })
    
    ```
    
    ```{r}
    
    renderValueBox({
      valueBox(
        value = nrow(selectedData()),
        icon = "fa-area-chart",
        color = ifelse(nrow(selectedData()) < 50, "warning", "primary")
      )
    })
    
    ```
    
    ### Ratings Gauge
    
    ```{r}
    
    renderGauge({
      gauge(round(mean(selectedData()$Metascore,na.rm = TRUE),2), 
            min = 0, max = 100, 
          gaugeSectors(
      success = c(80, 100), warning = c(40, 79), danger = c(0, 39)
    ))
    })
    
    ```
    
    
    Row {data-width=650}
    ------------------------ 
    ### 년도별 영화 매출 추이(전체)
    
    ```{r}
    
     YEAR1 = DATA %>%
      group_by(Year) %>%
      dplyr::summarise(MEAN = mean(Revenue..Millions.,na.rm = TRUE),
                       MEDIAN = median(Revenue..Millions.,na.rm = TRUE))
     p = ggplot(YEAR1) +
      geom_line(aes(x=Year,y=MEAN),group = 1 , col ='red') +
      geom_point(aes(x=Year,y=MEAN), col ='red') +
      geom_line(aes(x=Year,y=MEDIAN),group = 1 , col = 'royalblue') +
      geom_point(aes(x=Year,y=MEDIAN) , col = 'royalblue') +
      xlab("년도") + ylab("매출액") 
     
     ggplotly(p)
     
    ```
    
    ### 년도별 영화 매출 추이(장르 선택)
    
    ```{r}
    
    renderPlotly({
     YEAR2 = selectedData() %>%
      group_by(Year) %>%
      dplyr::summarise(MEAN = mean(Revenue..Millions.,na.rm = TRUE),
                       MEDIAN = median(Revenue..Millions.,na.rm = TRUE))
     p = ggplot(YEAR2) +
      geom_line(aes(x=Year,y=MEAN),group = 1 , col ='red') +
      geom_point(aes(x=Year,y=MEAN), col ='red') +
      geom_line(aes(x=Year,y=MEDIAN),group = 1 , col = 'royalblue') +
      geom_point(aes(x=Year,y=MEDIAN) , col = 'royalblue') +
      xlab("년도") + ylab("매출액") 
     
     ggplotly(p)
    })
    
    ```
    
    Row {data-width=650}
    ------------------------ 
    ### 데이터 테이블
    ```{r}
    selectedData2 = reactive({
      subset(DATA,FIRST_GENRE==input$Genre & Rating > input$Rating)
    })
    ```
    
    ```{r}
    renderTable({
     DF = selectedData2()[,c(2,3,5:10,34)]
     DF[order(-DF$Rating),]
    })
    
    ```