Search code examples
ruser-interfaceservershinyreusability

How to use the result of using reactive function as input in ui? - r shiny


I used a reactive function on the server to create a data frame.

And I want to express the unique vector of one column of this data frame as selectinput in the UI.

ex)

DATA<-data.frame(ID, NAME)

####server#####
DATAFRAME<-reactive({DATA[DATA$ID %in% input$ID,})

####UI######
selectizeInput("name",label="name:",choices=unique(DATAFRAME$NAME))

In other words, I want to show a list of Names for data that has been refined once by ID in advance.


Solution

  • In order to react to changes in the reactive expression DATAFRAME you can use an observer and update the list of names with updateSelectizeInput (as pointed out by @MrFlick).

    library(shiny)
    
    ui <- fluidPage(
        titlePanel("Widget Dependencies Sample App"),
        selectizeInput("IdSelect", "Choose ID", "N/A"), # IDs to select from
        selectizeInput("IdName", "Choose Name", "N/A"), # Names depend on selected ID
        tableOutput("IdDatatable") # show the whole data set to understand what happens
    )
    
    server <- function(input, output, session) {
      ID   <- paste("ID", 1:3, sep = "_")
      NAME <- LETTERS[1:(3*5)]
      DATA <- data.frame(ID, NAME)
      updateSelectizeInput(session, "IdSelect", choices = unique(ID))
    
      DATAFRAME <- reactive({DATA[DATA$ID %in% input$IdSelect, ]})
    
      observe({
       updateSelectizeInput(session, "IdName", choices = unique(DATAFRAME()$NAME))
      })
    
      output$IdDatatable <- renderTable(DATA)
    }
    
    shinyApp(ui = ui, server = server)
    

    However, if you need the reactive expression DATAFRAME only once, you can make the code even simpler. In that case, you wouldn't observe a DATAFRAME that reacts to changes in a widget. You can omit the DATAFRAMEand observe the input widget directly. This observer generates a filtered vector of Names and changes the choices in the selectizeInput with only one observer.

    observe({
        Names <- DATA$NAME[DATA$ID %in% input$IdSelect]
        updateSelectizeInput(session, "IdName", choices = unique(Names))
    })