Как повторно использовать selectInput из uiOutput и renderUI? - PullRequest
0 голосов
/ 05 июля 2019

Как мы можем повторно использовать uiOutput, используемый для выпадающих списков selectInput, для повторного использования columns2 в функции сервера и отображения в пользовательском интерфейсе?

Блестящий renderUI selectInput вернул NULL

runApp(list(
  ui = bootstrapPage(
    selectInput('dataset', 'Choose Dataset', c('mtcars', 'iris')),
    uiOutput('x'),
    uiOutput('y'),
    plotOutput('plot')
  ),
  server = function(input, output){
    output$x= renderUI({
      mydata = get(input$dataset)
      selectInput('columns2', 'X axis', names(mydata))
    })
    output$y = renderUI({
      mydata = get(input$dataset)
      selectInput('columns3', 'Y axis', names(mydata))
    })
    output$plot = renderPlot({
      # How to use the x, y to plot something e.g Petal.Width vs Petal.Length
      plot(x,y)
    })
  }
))

В основном график из этих selectInput

###############

Модульная версия

Почему эта заметка допускает использование значений selectInput на серверефункция?

library(shiny)
library(tidyverse)

mod_ui <- function(id){
  ns <- shiny::NS(id)
  shiny::tagList(
  selectInput('dataset', 'Choose Dataset', c('mtcars', 'iris')),
  uiOutput(ns('x')),
  uiOutput(ns('y')),
  plotOutput(ns('plot'))
  )
}

mod_server =  function(input, output, session, file) {

  output$x= renderUI({
    mydata =  reactive({ 
get(input$dataset)
})
    ### ?? Should ns() be applied here as well ? 
    selectInput(ns('columns2'), 'X axis', names(mydata))
  })
  output$y = renderUI({
    mydata = get(input$dataset)
    ### ?? Should ns() be applied here as well ?
    selectInput(ns('columns3'), 'Y axis', names(mydata))
  })

  output$plot = renderPlot({
    req(input$columns2, input$columns3)
      x <- input$columns2
      y <- input$columns3
      if(all(c(x,y) %in% names(mydata()))){ # to avoid an error when the user changes the dataset
        plot(mydata()[[x]], mydata()[[y]], xlab = x, ylab = y)
      }
  })
}


ui <- 

  shinydashboard::dashboardPage(
    skin = "yellow",
    shinydashboard::dashboardHeader(
      title = "Modularizing App"
    ),
    shinydashboard::dashboardSidebar(
      shinydashboard::sidebarMenu(id = "menu",
                                  shinydashboard::menuItem('Example', tabName = 'example')
      )
    ),
    shinydashboard::dashboardBody(
      shinydashboard::tabItems(
        shinydashboard::tabItem("example", mod_ui("ui"))
      )
    )
  )

server <- function(input, output) {
  displayFile <- shiny::callModule(mod_server, "ui")
}

shinyApp(ui,server)

1 Ответ

1 голос
/ 05 июля 2019

Я думаю, что вы хотите:

runApp(list(
  ui = bootstrapPage(
    selectInput('dataset', 'Choose Dataset', c('mtcars', 'iris')),
    uiOutput('x'),
    uiOutput('y'),
    plotOutput('plot')
  ),
  server = function(input, output){
    mydata <- reactive({
      get(input$dataset)
    })
    output$x= renderUI({
      selectInput('columns2', 'X axis', names(mydata()))
    })
    output$y = renderUI({
      selectInput('columns3', 'Y axis', names(mydata()))
    })
    output$plot = renderPlot({
      req(input$columns2, input$columns3)
      x <- input$columns2
      y <- input$columns3
      if(all(c(x,y) %in% names(mydata()))){ # to avoid an error when the user changes the dataset
        plot(mydata()[[x]], mydata()[[y]], xlab = x, ylab = y)
      }
    })
  }
))

Модульное приложение

Основной причиной, по которой модульное приложение не работает, является отсутствие ns в selectInput:

    selectInput('dataset', 'Choose Dataset', c('mtcars', 'iris'))

заменить на

    selectInput(ns('dataset'), 'Choose Dataset', c('mtcars', 'iris'))

Полный код:

library(shiny)

mod_ui <- function(id){
  ns <- shiny::NS(id)
  shiny::tagList(
    selectInput(ns('dataset'), 'Choose Dataset', c('mtcars', 'iris')),
    uiOutput(ns('x')),
    uiOutput(ns('y')),
    plotOutput(ns('plot'))
  )
}

mod_server =  function(input, output, session, file) {

  ns <- session$ns

  mydata = reactive({ 
    get(input$dataset)
  })

  output$x = renderUI({
    selectInput(ns('columns2'), 'X axis', names(mydata()))
  })
  output$y = renderUI({
    selectInput(ns('columns3'), 'Y axis', names(mydata()))
  })

  output$plot = renderPlot({
    req(input$columns2, input$columns3)
    x <- input$columns2
    y <- input$columns3
    if(all(c(x,y) %in% names(mydata()))){ # to avoid an error when the user changes the dataset
      plot(mydata()[[x]], mydata()[[y]], xlab = x, ylab = y)
    }
  })
}


ui <- shinydashboard::dashboardPage(
    skin = "yellow",
    shinydashboard::dashboardHeader(
      title = "Modularizing App"
    ),
    shinydashboard::dashboardSidebar(
      shinydashboard::sidebarMenu(id = "menu",
                                  shinydashboard::menuItem('Example', tabName = 'example')
      )
    ),
    shinydashboard::dashboardBody(
      shinydashboard::tabItems(
        shinydashboard::tabItem("example", mod_ui("ui"))
      )
    )
  )

server <- function(input, output, session) {

  displayFile <- shiny::callModule(mod_server, "ui")

}

shinyApp(ui,server)
...