updateSelectInput does not update the input$id value of the selectInput

Hello,
I am working on a little app for educational purposes that is supposed to show plots of data uploaded by the user. The user is asked to upload a csv data file and then to select two variables form said file which will then be plotted (I have a repex of my app below). I have also provided the code for two data files which can be used with the repex: uniformData.csv contains two columns of data from uniform distributions and a grouping column; normalData.csv contains two columns of data from normal distributions and a grouping column. In the example I am describing below I first upload uniformData.csv, select the x_unif and the y_unif variables for plotting, then upload the normalData.csv.

Since the idea was that the user can upload their own data and try out multiple data file if they wish, I update the selectInput control options of my app with an observeEvent() and updateSelectInput() every time the user uploads a new data file. This works fine. I want to let the user pick the variables of their choice and thus I have set selected = character(0) in my calls to updateSelectInput(). I do not want the first column of the uploaded data file to be automatically selected, because I want the user to consciously choose their x and y variables.

The first cycle of the app works fine. I can upload a data file (e.g. uniformData.csv), select an x (x_unif) and a y (y_unif) variable and the plot gets generated. However, problems arise when a new file is uploaded. I upload a data file, the choices for the two selectInput controls get updated but I get an error for my plot. This error seemingly results from the fact that even though I used updateSelectInput() and set selected = character(0), the value of input$x as well as the value of input$y do not change after a new data file has been uploaded. The value of input$x is still "x_unif" and the value of input$y remains "y_unif" (if one uploads the uniformData.csv and selects the respective x and y variables). I thought that setting selected = character(0) would set the value of input$x and input$y to "". As a result the x() and y() reactive expression should be invalidated and thus the plot would simply not be drawn and the red error message can be circumvented.

Does anyone reading this know of a way to set input$x and input$y = "" with updateSelectInput() or with some other method? I unfortunately know zero JavaScript, which might solve the issue? I would be grateful for any ideas and thank you in advance.

library(shiny)
ui <- fluidPage(fluidRow(
  column(
    width = 4,
    fileInput(
      inputId = "file",
      label = "Upload your datafile",
      accept = ".csv"
    ),
    selectInput(
      inputId = "x",
      label = "Select x variable:",
      choices = NULL
    ),
    selectInput(
      inputId = "y",
      label = "Select a y variable",
      choices = NULL
    )
  ),
  column(
    width = 8,
    verbatimTextOutput("selectInputVal"),
    plotOutput("plot")
  )
  
))

server <- function(input, output, session) {
  data <- reactive({
    req(input$file)
    read.table(
      input$file$datapath,
      sep = ",",
      dec = ".",
      header = TRUE
    )
  })
  
  observeEvent(eventExpr = data(),
               handlerExpr = {
                 updateSelectInput(session,
                                   "x",
                                   choices = names(data()),
                                   selected = character(0))
                 
                 
                 updateSelectInput(session,
                                   "y",
                                   choices = names(data()),
                                   selected = character(0))
               })
  
  x <- reactive({
    req(data())
    req(input$x)
    data()[[input$x]]
  })
  
  y <- reactive({
    req(data())
    req(input$y)
    data()[[input$y]]
  })
  
  output$selectInputVal <- renderPrint(input$x)
  output$plot <- renderPlot({
    plot(x(), y())
  })
}
runApp(shinyApp(ui = ui, server = server))



# Create example data filies:
RNGversion("4.1.0")
set.seed(123)
normalData <- data.frame(
  x_norm = rnorm(n = 10, mean = 100, sd = 15),
  y_norm = rnorm(n = 10, mean = 50, sd = 10),
  grp_ab = sample(c("a", "b"), size = 10, replace = TRUE)
)

uniformData <- data.frame(
  x_unif = runif(n = 20, min = 0, max = 10),
  y_unif = runif(n = 20, min = -10, max = 10),
  grp_cd = sample(c("c", "d"), size = 20, replace = TRUE)
)

# write.csv(normalData, "normalData.csv", quote = FALSE, row.names = FALSE)
# write.csv(uniformData, "uniformData.csv", quote = FALSE, row.names = FALSE)

I recommend that you simply add appropriate guards on this function:


  output$plot <- renderPlot({
    plot(req(x()), req(y()))
  })

Thank you very much for your response.

Calling req() inside the renderPlot() function indeed removes the red error message for the example code. However, the code I provided is a much simplified version of the app I am writing, which is going to have several more select input controls which I wish to update the same way (i.e. I would like to set their respective "selected" values to character(0)). I unfortunately cannot work all the kinds of input controls I am planning into the repex, since it would make the repex quite long. If I can set the "selected" value to character(0) upon every update, it should fix all use cases within the app. Thus, while the solution with req() certainly works perfectly for the repex I provided, it might not solve my other updateSelectInput() problems. So if anyone has ideas on how to solve the updateSelectInput() "selected" value issue described above, I would really appreciate that as well.

In the meantime I will add req() everywhere I need to and thank you very much again for your suggestion.

This topic was automatically closed 54 days after the last reply. New replies are no longer allowed.

If you have a query related to it or one of the replies, start a new topic and refer back with a link.