0
votes

I am working on an app for educational purposes that is supposed to show plots of data uploaded by the user. The user is asked to upload a csv file and then to select two variables from said file which will be plotted. I have 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 try out multiple data files 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 the value of the selectInput does not get set to 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 "".

Does anyone 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({
    req(x(), y())
    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)