简体   繁体   中英

How to reuse the selectInput from uiOutput and renderUI?

How can we reuse the uiOutput used for selectInput drop downs to reuse the columns2 within Server function and display in UI ?

Shiny renderUI selectInput returned 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)
    })
  }
))

Basically a plot from these selectInput .

Modularised version

Why does this note accepting to use the values of selectInput within Server function ?

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)

I think you want:

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)
      }
    })
  }
))

Modularized app

The main reason the modularized app does not work is a missing ns in the selectInput :

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

to replace with

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

Full code:

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)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM