Ch3. Flexdashboard를 통한 Dashboard 만들기 1편
Dashboard 만드는 순서
출력 옵션 설정
- 대시보드 제목
- 페이지 제목
- 소스코드 삽입 여부
- 레이아웃 배치 기준 설정(행 기준 혹은 열 기준)
- 출력형식 설정
대시보드 레이아웃 구성
- 사이드바 삽입 여부
- Row 혹은 Column 을 추가함으로써 레이아웃 추가
그래프 추가
- 사이드바 혹은 배치된 Row & Column 배치 코드 밑에 그래프 추가
Rendor plot 및 plotly 추가 여부
- Rendor plot이란 대시보드에 직접 input parameter를 추가함으로써, input의 변경 여부에 따라 그래프가 변경되는 동적 대시보드를 만들고자 할 때 쓰이는 plot입니다.
- plotly는 그래프를 확대해서 볼 수도 있고, 마우스를 그래프에 위치시키면 그래프의 값이 나오게 되는 패키지입니다.
- Dashboard 출력 옵션 적용
- 시각화에 필요한 패키지 및 데이터 및 전처리 작업 진행
- Dashboard 페이지 이름 및 아이콘 설정(윗단 구성 완료)
- Dashboard 레이아웃 구성
- 전체 레이아웃
- 1번 레이아웃 배치 코드 (사이드바)
- 2번 레이아웃 배치 코드
- 3번 레이아웃 배치코드
- 4번 레이아웃 배치코드
- 5번 레이아웃 코드
참고 사이트 : https://rmarkdown.rstudio.com/flexdashboard/using.html
제가 사진으로 업로딩한 Dashboard 코드는 다음과 같습니다. 전체적인 구조를 한번 훑어보고 하나씩 따로 이해하는 것으로 진행하겠습니다.
참고로 이제부터 시작하는 코드들은 모두 markdown 문법형태입니다.
---
title: "LEARNIT" <!-- Dashboard 이름 설정 -->
output:
flexdashboard::flex_dashboard:
orientation: rows <!-- layout 배치를 행(row)이 늘어나는 식으로 배치 -->
source_code: embed <!-- Source code 삽입 -->
theme: readable
runtime: shiny
---
데이터 다운로드 링크 : 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
```
DASHBOARD CREATING {data-icon="fa-signal"} <!-- Dashboard 이름 설정 및 아이콘 설정 -->
========================== <!-- = 으로 분리하면 격자선이 생기면서 윗단 구성을 완료 -->
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를 써준 다음에 '-------------------'를 써서 구분지어주면 바로 배치가 완성이 됩니다.
일반적인 layout 배치도 다음과 같습니다 . Row를 선언해주고 '-------------------'를 써서 구분지어주면 배치는 완료됩니다. 그 밑에는 제목을 적어주고 컨텐츠를 작성해주면 됩니다.
Row {data-height=100} <!-- Row 를 선언해줌으로써 2번 레이아웃 배치 선선 -->
------------------------ <!-- 2번 레이아웃 배치코드 구분선 -->
### Target Of Dashboard <!-- 레이아웃 제목 정해주기 -->
parameter 설정에 따라 변경되는 동적 대시보드 만들기
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)
))
})
```
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)
})
```
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),]
})
```