1 shiny 모듈 튜토리얼1

shiny 웹앱에 모듈을 도입하게 되면 중복되는 코드도 줄어들고 추상화 개념을 가져와서 유지보수도 수월하고 가독성도 높일 수 있게 된다. 특히, 한 곳에 집중을 하기 때문에 훨씬 생산성을 높이고 버그도 줄일 수 있게 된다.

2 shiny 모듈 구조

shiny 웹앱을 모듈 개념을 도입하여 구현했을 경우 디렉토리와 파일은 다음과 같은 구조를 일반적으로 갖게 된다.

shiny 웹앱

shiny_app_name
|___ server.R
|___ ui.R

모듈 도입 후 shiny 웹앱

shiny_app_name
|___ server.R
|___ ui.R
|
|___ modules
    |___ module_1.R
    |___ module_2.R

:::

한걸음 더 들어가 하나의 모듈을 여러 shiny 웹앱에서 사용되는 경우를 살펴보자.

모듈 도입 전 shiny 웹앱

shiny_app_name1    shiny_app_name2      shiny_app_name3
|___ server.R      |___ server.R         |___ server.R 
|___ ui.R          |___ ui.R             |___ ui.R     

모듈 도입 후 shiny 웹앱

shiny_module
|___ module_1.R
|___ module_2.R

shiny_app_name1    shiny_app_name2      shiny_app_name3
|___ server.R      |___ server.R         |___ server.R 
|___ ui.R          |___ ui.R             |___ ui.R     

:::

3 간단한 모듈

3.1 헬로 월드

shiny 모듈이 없는 일반적인 shiny 웹앱을 제작해 보자.

3.1.1 파일 디렉토리 구조

helloworld
|___ app.R

3.1.2 app.R

library(shiny)

ui <- fluidPage(
    
    titlePanel("Shiny 모듈이 없이 구현된 헬로월드"),
    
    fluidRow(
        column(2, textInput("TI_username", label = NULL, placeholder = "이름을 입력하세요.")),
        column(2, actionButton("AB_hello", label = "버튼을 누르세요 !"))
    ),
    br(),
    hr(),
    br(),
    fluidRow(
        column(12, textOutput("TO_Hello_user"))
    )
    
)

server <- function(input, output, session) {
    
    # 버튼을 클릭했을 때 텍스트 입력값을 리액티브로 반환
    name <- eventReactive(input$AB_hello, {
        return(input$TI_username)
    })
    
    # 헬로월드 출력결과
    output$TO_Hello_user <- renderText({
        if (name() %in% "") {
            return("헬로 월드 !")
        } else {
            return(paste("안녕 세상 ~~~", name(), "님, 환영합니다!!!"))
        }
    })
}

shinyApp(ui = ui, server = server)

3.1.3 실행결과

3.2 모듈 헬로 월드

shiny 모듈로 제작한 헬로월드 shiny 웹앱은 다음과 같다.

3.2.1 파일 디렉토리 구조

hellowrold_module
|___ app.R
|
|___ modules
    |___ helloworld_module.R

3.2.2 app.R

library(shiny)

getwd()

source("module/helloworld_module.R", encoding = "UTF-8")

ui <- fluidPage(
    
    titlePanel("Shiny 모듈 도입하여 구현된 헬로월드"),
    
    fluidRow(
        hello_world_UI(id = "id_1")
    )
    
)

server <- function(input, output, session) {
    
    hello_world_server(id = "id_1")
    
}

shinyApp(ui = ui, server = server)

3.2.3 helloworld_module.R

# Function for module UI
hello_world_UI <- function(id) {
  
  ns <- NS(id)
  
  fluidPage(
    fluidRow(
      column(2, textInput(ns("TI_username"), label = NULL, placeholder = "이름을 입력하세요.")),
      column(2, actionButton(ns("AB_hello"), label = "버튼을 누르세요 !"))
    ),
    hr(),
    fluidRow(
      column(12, textOutput(ns("TO_Hello_user")))
    )
  )
  
}

# 모듈 함수
hello_world_server <- function(id) {
  
  moduleServer(id, function(input, output, session) {
  
    # 버튼을 클릭했을 때 텍스트 입력값을 리액티브로 반환
    name <- eventReactive(input$AB_hello, {
      return(input$TI_username)
    })
    
    # 헬로월드 출력결과
    output$TO_Hello_user <- renderText({
      if (name() %in% "") {
        return("헬로 월드 !")
      } else {
        return(paste("안녕 세상 ~~~", name(), "님, 환영합니다!!!"))
      }
    })
  
  })
}

3.2.4 실행결과

 

데이터 과학자 이광춘 저작

kwangchun.lee.7@gmail.com