Shiny R Choices Label and Choices Index

,

Good morning,

I'm more than likely not asking the correct question, but I can't seem to find any information on this. When looking at the options for a shiny selectInput, I also don't see what I'm looking for.

selectInput(
  inputId,
  label,
  choices,
  selected = NULL,
  multiple = FALSE,
  selectize = TRUE,
  width = NULL,
  size = NULL
)

Is there a way to have a choicesLabel option (currently known as choices) as well as a choicesIndex (currently doesn't seem to be an option)?

The scenario would be you have a label column and an index column in your data set. Say the label requires an update but the index (primary key) column remains the same. By having a choiciesIndex drive the application and not the choicesLabel (which is the choices option currently), we wouldn' need to update the application when a label changes.

If this is currently possible, can you point me to the documentation?
Thank you

Not sure that this is what you ask for, but choices can be defined as a named list with indices, as in

selectInput(inputId = "separator", label = "Column separation", choices = list("Blank/Tab" = 1, "Comma" = 2, "Semi-colon" = 3), selected = 1, multiple = F, selectize = T)

where input$separator can be 1 (default), 2 or 3

Thank you Alvarosg,

This looks like it would be what I am after. Is there a way to make a dynamic list from two columns in a data set?

Thank you for sharing this. I was looking at this all wrong :slight_smile:.

I'm glad it helped.

You could leave a uiOutput() on the UI side and then fill it with a selectInput() inside a renderUI() on the server side, where you can define the choices list dynamically using a reactive that reads the data set.

All these functions are well documented with examples.

I'd suggest using updateSelectizeInput instead of renderUI. Updating an existing element is faster than re-rendering it:

library(shiny)

ui <- fluidPage(
  numericInput("nrows", "Number of rows", value = 10L, min = 10L),
  selectizeInput("dynamic_selectizeInput", "dynamic_selectizeInput", choices = NULL)
)

server <- function(input, output, session) {
  DF <- reactive({
    data.frame(value = seq_len(input$nrows), label = paste0("label_", seq_len(input$nrows)))
  })
  
  dynamic_list <- reactive({
    setNames(as.list(DF()$value), DF()$label)
  })
  
  observe({
    updateSelectizeInput(session, "dynamic_selectizeInput", choices = dynamic_list(), selected = isolate(input$dynamic_selectizeInput))
  })
}

shinyApp(ui, server)
2 Likes

Great solution!

My only suggestion would be to use the pull function to create the named list.

library(shiny)

ui <- fluidPage(
  numericInput("nrows", "Number of rows", value = 10L, min = 10L),
  selectizeInput("dynamic_selectizeInput", "dynamic_selectizeInput", choices = NULL)
)

server <- function(input, output, session) {
  DF <- reactive({
    data.frame(
      value = seq_len(input$nrows), 
      label = paste0("label_", seq_len(input$nrows)))
  })
  
  dynamic_list <- reactive({
    DF() %>% pull(value,label)
  })
  
  observe({
    updateSelectizeInput(session,
       "dynamic_selectizeInput", 
       choices = dynamic_list(), 
       selected = isolate(input$dynamic_selectizeInput)
      )
  })
}

shinyApp(ui, server)

If eye-candy is desired, you'll have to add another dependency: library(dplyr) or use dplyr::pull :wink:

Well I suppose you could R without dpylr… :sweat_smile:

That's what I do for 13 years now - I'll stick with {data.table}
Cheers :slight_smile: