Shiny Doesn't Show Me the Entire Selectinput When I Have Choices > 1000

Shiny doesn't show me the entire selectInput when I have choices 1000

Use selectizeInput instead of selectInput with the argument options = list(maxOptions = 3000).

selectInput not showing the choices and resetting values to 'All' in shinyApp

I've done several modifications in your code. In particular, I've added some req's (see ?req), and in output$disp_selector I've modified available:

available <- data_table[["disp"]][data_table$vs %in% input$vs]
if(! "All" %in% input$carb){
available <- available[data_table$carb %in% input$carb]
}

data_table<-mtcars    

#ui
ui = fluidPage(
sidebarLayout(
sidebarPanel (

uiOutput("vs_selector"),
uiOutput("carb_selector"),
uiOutput("disp_selector")),

mainPanel(

DT::dataTableOutput('mytable')

)

))

#server
server = function(input, output, session) {

output$vs_selector <- renderUI({

selectInput(inputId = "vs",
label = "vs:", multiple = TRUE,
choices = c( unique(data_table$vs)),
selected = c(0,1))

})

output$carb_selector <- renderUI({

req(input$vs)

available0 <- data_table[c(data_table$vs %in% input$vs ), "carb"]

selectInput(
inputId = "carb",
label = "carb:",
multiple = TRUE,
choices = c('All',as.character(unique(available0))),
selected = 'All')

})

output$disp_selector <- renderUI({
req(input$vs, input$carb)

available <- data_table[["disp"]][data_table$vs %in% input$vs]
if(! "All" %in% input$carb){
available <- available[data_table$carb %in% input$carb]
}

selectInput(
inputId = "disp",
label = "disp:",
multiple = TRUE,
choices = c('All',as.character(unique(available))),
selected = 'All')

})

thedata <- reactive({

req(input$disp, input$vs, input$carb)

data_table<-data_table[data_table$vs %in% input$vs,]

if(! "All" %in% input$carb){
data_table<-data_table[data_table$carb %in% input$carb,]
}

if(! "All" %in% input$disp){
data_table<-data_table[data_table$disp %in% input$disp,]
}

data_table

})

output$mytable = DT::renderDataTable({

DT::datatable( {

thedata() # Call reactive thedata()

})

})

}

shinyApp(ui = ui, server = server)

FYI, for a cleaner solution, you might be interested in selectizeGroupUI in the shinyWidgets package:

library(shiny)
library(shinyWidgets)

ui <- fluidPage(
fluidRow(
column(
width = 10, offset = 1,
tags$h3("Filter data with selectize group"),
panel(
selectizeGroupUI(
id = "my-filters",
params = list(
disp = list(inputId = "disp", title = "disp:"),
carb = list(inputId = "carb", title = "carb:"),
vs = list(inputId = "vs", title = "vs:")
)
), status = "primary"
),
dataTableOutput(outputId = "table")
)
)
)

server <- function(input, output, session) {
res_mod <- callModule(
module = selectizeGroupServer,
id = "my-filters",
data = mtcars,
vars = c("disp", "carb", "vs")
)
output$table <- renderDataTable(res_mod())
}

shinyApp(ui, server)

How to make selectInput choices reactive?

You should avoid renderUI where possible and use update* functions instead - updating is faster than re-rendering:

library(shiny)
library(data.table)

DT <- data.table(
ID = c(1, 1, 1, 2, 2, 2, 3, 3, 3),
Period = c(1, 2, 3, 1, 2, 3, 1, 2, 3),
Values = c(5, 10, 15, 0, 2, 4, 3, 6, 9)
)

all_choices <- unique(DT$Period)

ui <- fluidPage(
tableOutput("data"),
selectizeInput(
inputId = "fromPeriod",
label = "From period:",
choices = setdiff(all_choices, last(all_choices)),
selected = 1
),
selectizeInput(
inputId = "toPeriod",
label = "To period:",
choices = setdiff(all_choices, first(all_choices)),
selected = 2
),
tableOutput("dataSelect")
)

server <- function(input, output, session) {
output$data <- renderTable({
DT
})

observeEvent(input$fromPeriod, {
freezeReactiveValue(input, "toPeriod")
updateSelectizeInput(
session,
inputId = "toPeriod",
choices = all_choices[all_choices > input$fromPeriod],
selected = max(all_choices[all_choices > input$fromPeriod])
)
}, ignoreInit = TRUE)

output$dataSelect <- renderTable({
# in one line, however you seem to need part1 / part2 for your custom function
# setorder(DT[Period %in% c(input$fromPeriod, input$toPeriod)], Period)
part1 <- DT[Period == input$fromPeriod]
part2 <- DT[Period == input$toPeriod]
rbindlist(list(part1, part2))
}, rownames = TRUE)
}

shinyApp(ui, server)

To avoid triggering reactives or outputs unnecessarily you should almost alway use freezeReactiveValue when using a update* function in shiny. Please see this related chapter from Mastering Shiny.

Updating selection of server-side selectize input with 1000 choices fails

The short answer is explicitly re-specify your choices and server in your update.

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

myChoices <- paste("Item", 1:10000)

updateSelectizeInput(session, "listid", choices = myChoices, server = T)
observeEvent(input$buttonid,
{
updateSelectizeInput(session, "listid",
server = TRUE,
choices = myChoices,
selected = "Item 1234")

})
}

The default for server in updateSelectizeInput is FALSE. This causes the code to drop into a control statement which uses updateSelectInput instead. From the function code

function (session, inputId, label = NULL, choices = NULL, selected = NULL, 
options = list(), server = FALSE)
{
...

if (!server) {
return(updateSelectInput(session, inputId, label, choices,
selected))
}

...

This sends a message to the client assuming all the choices are present (but as you mentioned, only the first 1000 are present).

Just setting server = TRUE results in an error when you click the button.

Warning: Error in [.data.frame: undefined columns selected
[No stack trace available]

I didn't fully trace the reason, but it ultimately creates an empty choices data.frame with an attribute denoting the selected value. I'm guessing somewhere else in function calls to the session object, this attribute is being used to try to select a column created from the empty data.frame.

The update function doesn't seem to change the choices stored on the server, so that's presumably why it's there when you search for it. During the changing the selected value, it seems to be trying to select from a NULL list of choices instead of the list of choices on the server.

It seems like you essentially have to recreate your selectizeInput when updating with a selected value beyond your initial list.

The ability to select ALL potential options in a Shiny input along with a dynamic table

Here is something to try out. You can use updateSelectInput to change your inputs and make them dependent. A separate reactive expression can filter your data based on your inputs. See if this gives you the intended behavior.

library(shiny)
library(DT)

State <- c("NV", "NV","NV", "MD", "MD", "MD", "MD", "NY", "NY", "NY", "OH", "OH", "OH")
County <- c("CLARK", "WASHOE", "EUREKA", "MONTGOMERY", "HOWARD", "BALTIMORE", "FREDERICK", "BRONX", "QUEENS", "WESTCHESTER", "FRANKLIN", "SUMMIT", "STARK" )
City <- c("Las Vegas", "Reno", "Eureka", "Rockville", "Columbia", "Baltimore", "Thurmont", "Bronx", "Queens", "Yonkers", "Columbus", "Akron", "Canton")
Rating<- c(1,2,3,4,5,6,7,8,9,10,11,12,13)
df <- data.frame(State, County, City, Rating, stringsAsFactors = F)

ui <- fluidPage(
titlePanel("Test Dashboard "),
sidebarLayout(
sidebarPanel(
selectInput("data1", "Select State", choices = c("All", unique(df$State))),
selectInput("data2", "Select County", choices = NULL),
selectInput("data3", "select City", choices = NULL)
),
mainPanel(
DTOutput("table")
)
))

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

observeEvent(input$data1, {
if (input$data1 != "All") {
updateSelectInput(session, "data2", "Select County", choices = c("All", unique(df$County[df$State == input$data1])))
} else {
updateSelectInput(session, "data2", "Select County", choices = c("All", unique(df$County)))
}
}, priority = 2)

observeEvent(c(input$data1, input$data2), {
if (input$data2 != "All") {
updateSelectInput(session, "data3", "Select City", choices = c("All", unique(df$City[df$County == input$data2])))
} else {
if (input$data1 != "All") {
updateSelectInput(session, "data3", "Select City", choices = c("All", unique(df$City[df$State == input$data1])))
} else {
updateSelectInput(session, "data3", "Select City", choices = c("All", unique(df$City)))
}
}
}, priority = 1)

filtered_data <- reactive({
temp_data <- df
if (input$data1 != "All") {
temp_data <- temp_data[temp_data$State == input$data1, ]
}
if (input$data2 != "All") {
temp_data <- temp_data[temp_data$County == input$data2, ]
}
if (input$data3 != "All") {
temp_data <- temp_data[temp_data$City == input$data3, ]
}
temp_data
})

output$table <- renderDT(
filtered_data()
)

}

shinyApp(ui, server)

R shiny passing reactive to selectInput choices

You need to use renderUI on the server side for dynamic UIs. Here is a minimal example. Note that the second drop-down menu is reactive and adjusts to the dataset you choose in the first one. The code should be self-explanatory if you have dealt with shiny before.

runApp(list(
ui = bootstrapPage(
selectInput('dataset', 'Choose Dataset', c('mtcars', 'iris')),
uiOutput('columns')
),
server = function(input, output){
output$columns = renderUI({
mydata = get(input$dataset)
selectInput('columns2', 'Columns', names(mydata))
})
}
))

EDIT. Another Solution using updateSelectInput

runApp(list(
ui = bootstrapPage(
selectInput('dataset', 'Choose Dataset', c('mtcars', 'iris')),
selectInput('columns', 'Columns', "")
),
server = function(input, output, session){
outVar = reactive({
mydata = get(input$dataset)
names(mydata)
})
observe({
updateSelectInput(session, "columns",
choices = outVar()
)})
}
))

EDIT2: Modified Example using parse. In this app, the text formula entered is used to dynamically populate the dropdown menu below with the list of variables.

library(shiny)
runApp(list(
ui = bootstrapPage(
textInput("text", "Enter Formula", "a=b+c"),
uiOutput('variables')
),
server = function(input, output){
outVar <- reactive({
vars <- all.vars(parse(text = input$text))
vars <- as.list(vars)
return(vars)
})

output$variables = renderUI({
selectInput('variables2', 'Variables', outVar())
})
}
))

Multiple reactive selectinput based on another in R shiny

Set choices to NULL within renderUI and update it via updateSelectInput while keeping the current selection:

 output$sources <- renderUI({
selectInput(
inputId = "SOURCE",
"Select source",
choices = NULL,
multiple = T
)
})

observeEvent(var_source(),{
updateSelectInput(
inputId = "SOURCE",
choices = var_source(),
selected = input$SOURCE
)
})

shiny::selectInput(): Unable to remove an element/variable based on index

Is this what you want?

library(shiny)
data <- c("cultivar","control", "stress")

ui <- fluidPage(
selectInput("select1", "Select variable", choices = data),
uiOutput("UiSelect2")
)

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

output$UiSelect2 <- renderUI({
#remove the selected element based on index
newData <- data[!data %in%input$select1]
selectInput("select2","Select another variable", choices = newData)
})

}

shinyApp(ui, server)


Related Topics



Leave a reply



Submit