이번에 준비한 튜토리얼은 제 강의를 듣는 과거-현재-미래 수강생분들을 위해 준비한 자료이다. 많은 도움이 되기를 바란다
이번에 준비한 Tutorial 코로나 세계현황을 Shiny Dashboard
로 만들어 가는 과정을 담았다.
지난시간에 Shiny에 관한 대략적인 소개를 했다. 처음 이 페이지를 방문한 사람들 위해 shiny tutorial 01 - get started 에서 짧게 확인하기를 바란다.
아래 샘플 코드를 확인하자.
# load the shiny package
library(shiny)
# 화면 구성 (UI) - 프론트엔드
ui <- fluidPage(
numericInput(inputId = "n", label = "Sample size", value = 25),
plotOutput(outputId = "hist")
)
# 서버 구성 - 벡엔드
server <- function(input, output) {
output$hist <- renderPlot({
hist(rnorm(input$n))
# 결과물을 만들어내는 코드 작성
})
}
# shiny app 호출
# 프로젝트 진행 시, 폴더 안에
# 파일명은 app.R 형태로 저장한다.
shinyApp(ui = ui, server = server)
##
## Listening on http://127.0.0.1:7908
Shiny
의 기본 구조는 UI
, Server
, shinyApp
형태로 구성이 된다. - UI
: 사용자 인터페이스, 즉 화면단을 만드는 작업을 진행한다. - Server
: 사용자 인터페이스가 제대로 기능할 수 있도록 지원하며, Server
단에서, 데이터 전처리, 수집, 시각화 작업이 이루어진다. 즉, 이 때에는 R의 문법이 사용되는 것이다. - shinyApp
: UI
와 Server
객체별로 저장이 되면, shinyApp
을 통해 호출하면서 실행이 된다.
각각의 App이 복잡하면 복잡해질 수록 UI
, Server
, shinyApp
의 파일로 재구현되어 관리가 될 수 있으며, Modularizing
의 개념도 함께 들어간다. 즉, 이 때부터는 웹개발 로직의 형태와 비슷하게 전개되는데, 이제 프로그래밍에 입문하는 사람들을 위해서는 추천하지 않는다. Shiny
를 추천하는 이유는 빠른 프로토타입이 가능해서이기 때문에, 가급적 이 원칙을 지켰으면 좋겠다. 냉정하게 말하면 복잡해질 것 같으면, 여기서부터는 고민해야 한다. BI Tool을 쓸것인가? 아니면 프론트개발자와 협업을 할 것인가?
만약, 조금 더 복잡한 ShinyApp
을 개발하고 싶다면, 아래 글에서 추가적인 개념을 익혔으면 한다.
다시 추가로 말하자면, 여기서부터는 데이터분석가(Data Analyst)
의 역량보다는 프론트엔드 개발자(Front-End Developer)
의 역량의 성격이 훨씬 더 짙어진다. 이 부분은 꼭 참고하기를 바란다.
사용자에게 보여주는 화면을 만들어주는 역할을 하며, 보통 Input & Output
function으로 통용된다. 대표적인 함수는 아래와 같다.
대표적인 Input
관련 함수는 아래와 같다. - textInput()
: 사용자가 텍스트를 입력할 수 있다. - dateRangeInput()
: 사용자가 날짜 등을 입력할 수 있다. - fileInput()
: 사용자가 csv파일 등을 입력할 수 있다.
대표적인 Output
관련 함수는 아래와 같다. - textOutput()
: 입력한 텍스트가 출력된다. - tableOutput()
: 데이터프레임 등이 출력된다. - imageOutput()
: 이미지 등이 출력된다.
조금 더 자세한 내용이 함수가 궁금하다면, 강사의 강의안을 참조하거나 또는 Shiny Cheet Sheet에서 확인하기를 바란다. 마지막으로 전체 함수가 궁금한 수강생들은 Function Reference를 참고하기를 바란다.
이 때 중요한 것은 각 함수 안에서 inputId=your_inputId
또는 outputId=your_outputId
가 중요하다. 각각의 ID명을 매개로 Server단과 연결이 되기 때문이다. 초반에 많은 에러들은 사실 여기에서 발생이 된다.
아래 샘플 코드를 보자.
ui <- fluidPage(
Input(inputId = myinput, label = mylabel, ...)
Output(outputId = myoutput, ...)
)
server <- function(input, output){
output$myoutput <- render*({
# code to build the output.
# If it uses an input value (input$myinput),
# the output will be rebuilt whenever
# the input value changes
})}
ui.R
에 있는 output
의 ID
명과, input
의 ID
명이 server.R
의 그것과 동일해야 한다.
ui
에서 파라미터(ex: outputId
) 형태로 값이 넘어오면 파라미터를 받아서 처리하고 결과를 보여준다. UI
에 있는 output()
함수들의 각각의 구성요소는 server
에서 render*()
함수와 연결이 된다. 예를 들면 아래와 같다.
output$hist <- renderPlot({
hist(rnorm(input$myinput))
})
renderPlot()
: 그래프 작성 결과를 출력하는 함수다.renderText()
: 텍스트 작성 결과를 출력하는 함수다.renderTable()
: 테이블 작성 결과를 출력하는 함수다.간단하게 ui와 server 관계를 정리하면 아래와 같다.
ui()
에서는 plotOutput(outputId = "myoutput")
, server()
에서는 output$myoutput <- renderPlot({...})
정리될 수 있고, 이 때 두 객체를 연결하는 인자는 ouputId
인 myouput
이다.
매우 간단한 소스코드를 입력하면서 ui
와 server
가 서로 어떻게 연동이 되는지 확인한다. 다만 이 때에는 numericInput
의 label
을 영어가 아닌 한글로 샘플수
라 명명했다.
# 패키지 로드
library(shiny)
# ui 디자인
ui <- fluidPage(
numericInput(inputId = "myNumber", label = "샘플수", value = 25),
plotOutput(outputId = "myHist")
)
# 서버 개발
# myHist와 myNumber를 꼭 확인한다.
server <- function(input, output) {
output$myHist <- renderPlot({
hist(rnorm(input$myNumber))
})
}
# shinyApp에서 ui와 server를 호출한다.
shinyApp(ui = ui, server = server)
##
## Listening on http://127.0.0.1:6753
Congratulation! You Mastered Shiny Structure.