简体   繁体   中英

Multiple reactive selectinput in R shiny

I have been using the following code to allow multiple select inputs to be reactive to each other. So when one is changed the values in the other boxes are updated:

l <- NULL
l$name <- c('b','e','d','b','b','d','e')
l$age <- c(20,20,21,21,20,22,22)
l <- as.data.frame(l)
l$name <- as.character(l$name)
l$age <- as.numeric(l$age)
library(shiny)

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

  data1 <- reactive({
    if(input$Box1 == "All"){
      l
    }else{
      l[which(l$name == input$Box1),]
    }
  })

  data2 <- reactive({
    if (input$Box2 == "All"){
      l
    }else{
      l[which(l$age == input$Box2),]
    }
  })

  observe({

    if(input$Box1 != "All"){
      updateSelectInput(session,"Box2","Choose an age", choices = c("All",unique(data1()$age)))
    }

    else if(input$Box2 != 'All'){
      updateSelectInput(session,"Box1","Choose a name", choices = c('All',unique(data2()$name)))
    }

    else if (input$Box1 == "All" & input$Box2 == "All"){
      updateSelectInput(session,"Box2","Choose an age", choices = c('All',unique(l$age)))
      updateSelectInput(session,"Box1","Choose a name", choices = c('All',unique(l$name)))
    }
  })


  data3 <- reactive({
    if(input$Box2 == "All"){
      data1()
    }else if (input$Box1 == "All"){
      data2()
    }else if (input$Box2 == "All" & input$Box1 == "All"){
      l
    }
    else{
      l[which(l$age== input$Box2 & l$name == input$Box1),]
    }
  })

  output$table1 <- renderTable({
    data3()
  })


})



ui <-shinyUI(fluidPage(
  selectInput("Box1","Choose a name", choices = c("All",unique(l$name))),
  selectInput("Box2","Choose an age", choices = c("All",unique(l$age))),
  tableOutput("table1")
))

shinyApp(ui,server)

This works great for 2 select input boxes but I am at a loss on how to add more.

I have a total of 4 selectinputs that need to be reactive to each other (as well as update a reactive dataframe).

I am new to R and Shiny.

If you're just trying to get the subsetted data and/or filter values then you're working way too hard. The DT package populates a input value with the indices of the filtered rows and automatically provides class appropriate filters. Note we use the subsetted_data() in a different render to produce more ui elements.

library("shiny")
library("DT")

ldata <- data.frame(
  name = c('b','e','d','b','b','d','e'),
  age  = c(20,20,21,21,20,22,22)
)

#

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

  output$ldata_table <- renderDataTable({
    datatable(ldata, filter = "top")
  })

  subsetted_data <- reactive({
    # the input$<shiny-id>_rows_all populated by the DT package,
    # gets the indices of all the filtered rows
    req(length(input$ldata_table_rows_all) > 0)

    ldata[as.numeric(input$ldata_table_rows_all),]
  })

  output$state <- renderPrint({
    summary(subsetted_data())
  })
})

ui <- fluidPage(
  dataTableOutput("ldata_table"),
  verbatimTextOutput("state")
)

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