Programing

큰 Shiny 앱을 구성하는 방법은 무엇입니까?

lottogame 2020. 12. 26. 09:24
반응형

큰 Shiny 앱을 구성하는 방법은 무엇입니까?


더 큰 Shiny 애플리케이션을 구성하는 모범 사례는 무엇입니까?
최고의 R 관행이 Shiny에도 적용될 수 있다고 생각합니다.
R 모범 사례는 여기에서 설명합니다. 대규모 R 프로그램을 구성하는 방법
Google의 R 스타일 가이드 링크 : 스타일 가이드

그러나 Shiny 코드를 더보기 좋게 (그리고 더 읽기 쉽게) 만들기 위해 채택 할 수있는 Shiny 컨텍스트에서 고유 한 팁과 트릭은 무엇입니까? 나는 다음과 같은 것을 생각하고있다.

  • Shiny에서 객체 지향 프로그래밍 활용
  • 에서 server.R어떤 부품 공급해야 하는가?
  • 마크 다운 문서, 그림, xml 및 소스 파일을 포함하는 프로젝트의 파일 계층 구조

예를 들어 내가 사용 navbarPage하고 tabsetPanel있고 모든 tabPanel코드에서 여러 UI 요소를 추가 한 후 매우 지저분 해 보입니다.

예제 코드 :

server <- function(input, output) {

 #Here functions and outputs..

}

ui <- shinyUI(navbarPage("My Application",
  tabPanel("Component 1",
             sidebarLayout(
                sidebarPanel(
                    # UI elements..
                ),
                mainPanel(
                    tabsetPanel(
                        tabPanel("Plot", plotOutput("plot")
                                 # More UI elements..
                                 ), 
                        tabPanel("Summary", verbatimTextOutput("summary")
                                 # And some more...
                                 ), 
                        tabPanel("Table", tableOutput("table")
                                 # And...
                                 )
                    )
                )
    )           
  ),
  tabPanel("Component 2"),
  tabPanel("Component 3")
))

shinyApp(ui = ui, server = server)

ui.R코드 를 구성하기 위해 GitHub에서 아주 좋은 솔루션을 찾았습니다. 빛나는 코드
솔루션은 renderUI모든 것을 렌더링하는 데 사용 하는 tabPanel것이며 server.R탭에서 다른 파일로 소싱됩니다.

server <- function(input, output) {

  # This part can be in different source file for example component1.R
  ###################################
  output$component1 <- renderUI({
        sidebarLayout(
                sidebarPanel(
                ),
                mainPanel(
                    tabsetPanel(
                        tabPanel("Plot", plotOutput("plot")), 
                        tabPanel("Summary", verbatimTextOutput("summary")), 
                        tabPanel("Table", tableOutput("table"))
                    )
                )
    )
  })
 #####################################  

}
ui <- shinyUI(navbarPage("My Application",
  tabPanel("Component 1", uiOutput("component1")),
  tabPanel("Component 2"),
  tabPanel("Component 3")
))

shinyApp(ui = ui, server = server)

R 광택 모듈추가 한 후 . 반짝이는 애플리케이션에서 복잡한 구조를 관리하는 것이 훨씬 쉬워졌습니다.

반짝이는 모듈에 대한 자세한 설명 : 여기

모듈 사용의 장점 :

  • 생성되면 쉽게 재사용 할 수 있습니다.
  • ID 충돌은 피하는 것이 더 쉽습니다.
  • 모듈의 입력 및 출력을 기반으로 한 코드 구성

탭 기반의 반짝이는 앱에서 하나의 탭은 입력출력 이있는 하나의 모듈로 간주 될 수 있습니다 . 그런 다음 탭의 출력을 입력으로 다른 탭에 전달할 수 있습니다.

모듈 식 사고를 활용하는 탭 기반 구조용 단일 파일 앱. 자동차 데이터 세트 를 사용하여 앱을 테스트 할 수 있습니다 . Joe Cheng에서 복사 한 코드의 일부 (첫 번째 링크). 모든 의견을 환영합니다.

# Tab module
# This module creates new tab which renders dataTable

dataTabUI <- function(id, input, output) {
  # Create a namespace function using the provided id
  ns <- NS(id)

  tagList(sidebarLayout(sidebarPanel(input),

                        mainPanel(dataTableOutput(output))))

}

# Tab module
# This module creates new tab which renders plot
plotTabUI <- function(id, input, output) {
  # Create a namespace function using the provided id
  ns <- NS(id)

  tagList(sidebarLayout(sidebarPanel(input),

                        mainPanel(plotOutput(output))))

}

dataTab <- function(input, output, session) {
  # do nothing...
  # Should there be some logic?


}

# File input module
# This module takes as input csv file and outputs dataframe
# Module UI function
csvFileInput <- function(id, label = "CSV file") {
  # Create a namespace function using the provided id
  ns <- NS(id)

  tagList(
    fileInput(ns("file"), label),
    checkboxInput(ns("heading"), "Has heading"),
    selectInput(
      ns("quote"),
      "Quote",
      c(
        "None" = "",
        "Double quote" = "\"",
        "Single quote" = "'"
      )
    )
  )
}

# Module server function
csvFile <- function(input, output, session, stringsAsFactors) {
  # The selected file, if any
  userFile <- reactive({
    # If no file is selected, don't do anything
    validate(need(input$file, message = FALSE))
    input$file
  })

  # The user's data, parsed into a data frame
  dataframe <- reactive({
    read.csv(
      userFile()$datapath,
      header = input$heading,
      quote = input$quote,
      stringsAsFactors = stringsAsFactors
    )
  })

  # We can run observers in here if we want to
  observe({
    msg <- sprintf("File %s was uploaded", userFile()$name)
    cat(msg, "\n")
  })

  # Return the reactive that yields the data frame
  return(dataframe)
}
basicPlotUI <- function(id) {
  ns <- NS(id)
  uiOutput(ns("controls"))

}
# Functionality for dataselection for plot
# SelectInput is rendered dynamically based on data

basicPlot <- function(input, output, session, data) {
  output$controls <- renderUI({
    ns <- session$ns
    selectInput(ns("col"), "Columns", names(data), multiple = TRUE)
  })
  return(reactive({
    validate(need(input$col, FALSE))
    data[, input$col]
  }))
}

##################################################################################
# Here starts main program. Lines above can be sourced: source("path-to-module.R")
##################################################################################

library(shiny)


ui <- shinyUI(navbarPage(
  "My Application",
  tabPanel("File upload", dataTabUI(
    "tab1",
    csvFileInput("datafile", "User data (.csv format)"),
    "table"
  )),
  tabPanel("Plot", plotTabUI(
    "tab2", basicPlotUI("plot1"), "plotOutput"
  ))

))


server <- function(input, output, session) {
  datafile <- callModule(csvFile, "datafile",
                         stringsAsFactors = FALSE)

  output$table <- renderDataTable({
    datafile()
  })

  plotData <- callModule(basicPlot, "plot1", datafile())

  output$plotOutput <- renderPlot({
    plot(plotData())
  })
}


shinyApp(ui, server)

Matt Leonawicz가 앱을 구성하는 방식이 정말 마음에 듭니다. 나는 Shiny를 사용하는 방법을 배우는 그의 접근 방식을 취했습니다. 우리 모두가 제대로 관리하지 않으면 상당히 흩어질 수 있다는 것을 알고 있기 때문입니다. 그의 구조를 살펴보면 run_alfresco 라는 앱에서 앱을 구성하는 방식에 대한 개요를 제공합니다.

https://github.com/ua-snap/shiny-apps


나는 Radiant를 썼다. 나는 사람들이 코드 구성에 대해 (아직) 나쁜 말을하는 것을들은 적이 없지만 그것이 더 나을 수 있다고 확신합니다. 한 가지 옵션은 Joe Cheng이 반짝이는 부분에서 수행하는 것처럼 ui와 논리를 분리하는 것입니다.

https://github.com/jcheng5/shiny-partials

Another might be to try OO programming, e.g., using R6 http://rpubs.com/wch/17459

ReferenceURL : https://stackoverflow.com/questions/27080089/how-to-organize-large-shiny-apps

반응형