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)