Update Shiny's 'Selectinput' Dropdown with New Values After Uploading New Data Using Fileinput

Update Shiny's 'selectInput' dropdown with new values after uploading new data using fileInput

I added reactive object myData that you have to use for table contents, but more importantly to update choices in selectInput (check observe and updateSelectInput part).

library(shiny)

ui <- shinyUI(
fluidPage(
fileInput("file1", "Choose file to upload", accept = ".rds"),
selectInput("myNames","Names", ""),
tableOutput("contents")
)
)

server <- function(input, output, session) {

myData <- reactive({
inFile <- input$file1
if (is.null(inFile)) {
d <- myDataFrame
} else {
d <- readRDS(inFile$datapath)
}
d
})

output$contents <- renderTable({
myData()
})

observe({
updateSelectInput(session, "myNames",
label = "myNames",
choices = myData()$names,
selected = myData()$names[1])
})

}

shinyApp(ui, server)

R-Shiny: Select input reactive on file input

updatedSelectInput should do it for you. Below is a minimal example.

To reduce package dependencies I switched to loading .csv rather than .xlsx. Note that the loaded file isn't validated, so if junk goes in you'll get junk out.

library(shiny)

#UI
ui <- fluidPage(

selectInput('mydropdown', label = 'Select', choices = 'No choices here yet'),

fileInput('myfileinput', label = 'Select File', accept = c(".csv"))

)

#Server
server <- function(input, output, session) {

observeEvent(input$myfileinput, {

mytable <- read.csv(input$myfileinput$datapath)

updateSelectInput(session, "mydropdown", label = "Select", choices = colnames(mytable))

})

}

shinyApp(ui = ui, server = server)

updateSelectInput does not update the input$id value of selectInput

The issue occurs because selectInput cannot handle character(0) as a valid selection since it is not listed in choices but when multiple = FALSE no selection possible either.

You can use selectizeInput, set multiple = TRUE which allows empty inputs but also limit it to only one selection via the maxItem option

library(shiny)
ui <- fluidPage(fluidRow(
actionButton("browser", "Browser"),
column(
width = 4,
fileInput(
inputId = "file",
label = "Upload your datafile",
accept = ".csv"
),
selectizeInput(
inputId = "x",
label = "Select x variable:",
multiple = TRUE,
choices = NULL,
options = list(maxItems = 1)
),
selectizeInput(
inputId = "y",
label = "Select a y variable",
multiple = TRUE,
choices = NULL,
options = list(maxItems = 1)
)
),
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 = input$file,
handlerExpr = {
updateSelectizeInput(session,
"x",
choices = names(data()),
selected = NULL)

updateSelectizeInput(session,
"y",
choices = names(data()),
selected = NULL)
})

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))

how to read and update the values of 'selectInput'

1) In the data reactive, you read the input field uploadedcsv, but in the ui, it's called uploadcsv (Note the missing ed). If you make this consistent, the upload should work.

2) The observe runs when the app starts; at that point data() returns NULL, so max(data()$Time is max(NULL), which is -Inf. You should wait until the data is loaded. One way to do this is to change observe to observeEvent:

observeEvent(data, { # and so on...

another option is to keep observe and add req(data) at the beginning of the observer.

Reactive select input to update table

Here is a quick prototype for your task

library(shiny)
library(tidyverse)
library(DT)

# 1. Dataset
df_demo <- data.frame(
age = c(16, 17, 18, 19, 20),
name = c("Peter", "Mary", "Mike", "Nick", "Phillipe"))

# 2. Server
server <- function(input, output, session) {

# 1. UI element 'Age'
output$ui_select_age <- renderUI({
selectInput("si_age", "Age", df_demo$age)
})

# 2. Reactive data set
df_data <- reactive({

# 1. Read UI element
age_selected <- input$si_age

# 2. Filter data
df <- df_demo %>%
filter(age == age_selected)

# 3. Return result
df
})

# 3. Datatable
output$dt_table <- renderDataTable({
datatable(df_data())
})

}

# 3. UI
ui <- fluidPage(
fluidRow(uiOutput("ui_select_age")),
fluidRow(dataTableOutput("dt_table"))
)

# 4. Run app
shinyApp(ui = ui, server = server)

Update on File Upload Shiny R

Hi don't pass variable to the global environnement, use shiny reactive feature instead, your server should be :

library(shiny)
library(ggplot2)

# Test data
# write.csv(x = iris, file = "iris.csv", row.names = FALSE)
# write.csv(x = data.frame(V1 = 1:10, V2 = rnorm(10)), file = "test.csv", row.names = FALSE)

shinyServer(function(input, output) {

tableData <- reactive({
inFile <- input$file1

if (!is.null(inFile)){
read.csv(inFile$datapath)
} else {
mtcars
}
})

#for x values
output$opt.x <- renderUI({
selectInput("xcolumn", "X column to Plot", names(tableData()))
})

output$your_data <- renderTable({
head(tableData())
})
})

And replace your main panel with :

mainPanel(
tableOutput("your_data")
)

I remove the params in read.csv since those input are not defined in the UI.

EDIT

Try this app, it's not a shiny solution but a jquery/js one (the difference is in the ui) (see this answer) :

library("shiny")
ui <- fluidPage(
titlePanel("App"),
sidebarLayout(
sidebarPanel(
fileInput('file1', 'Choose CSV File',
accept = c('.csv','.tsv')
),
tags$script(
'$( "#file1" ).on( "click", function() {
this.value = null;
});'
),
uiOutput("opt.x")
),
mainPanel(
tableOutput("your_data")
)
)
)
server <- function(input, output) {

tableData <- reactive({
inFile <- input$file1
if (!is.null(inFile)){
read.csv(inFile$datapath)
} else {
mtcars
}
})
#for x values
output$opt.x <- renderUI({
selectInput("xcolumn", "X column to Plot", names(tableData()))
})

output$your_data <- renderTable({
head(tableData())
})
}
shinyApp(ui = ui, server = server)

For testing I used :

write.csv(x = data.frame(V1 = 1:10, V2 = rnorm(10)), file = "test.csv", row.names = FALSE)
write.csv(x = data.frame(V11 = 11:20, V12 = rnorm(10), ABC = letters[1:10]), file = "test.csv", row.names = FALSE)

Update dropdown values in R shiny dynamically

You need to return the content within your if statements. You can do this using return

library(shiny)
library(shinyWidgets)

# Define the UI
ui <- bootstrapPage(
column(3, uiOutput("class_level")),
column(3,uiOutput("product"))
)

# Define the server code
server <- function(input, output) {

output$class_level <- renderUI({
selectInput(
"selected_class",
label = h4("Classification Level"),
choices = list(
"Brand" = "Brand",
"Brand1" = "Brand1",
"Brand2" = "Brand2"
),
selected = "Brand"
)
})

getFlavor <- reactive({

if (input$selected_class =="Brand") {
return(c( "a " = "a",
"b" = "b",
"c" = "c"
))
}
else if (input$selected_class =="Brand1")
{
return(c(
"1" = "1",
"2" = "2",
"3" = "3"
))
}
else (input$selected_class =="Brand2")
{
return(
c(
"x" = "x",
"y" = "y",
"z" = "z"
))
}

})

output$product <- renderUI({
pickerInput(
"selected_product",
label = h4("Product Family"),
choices = as.list(getFlavor()),
selected = as.list(getFlavor()),
options = list(
`deselect-all-text` = "None",
`select-all-text` = "Total",
`actions-box` = TRUE
),
multiple = F,
width = "100%"
)
})
}

# Return a Shiny app object
shinyApp(ui = ui, server = server)


Related Topics



Leave a reply



Submit