Rshiny: How to pass renderUI output to chocies parameter in Selectinput - r

I am trying to input renderUI output in server.UI as an input for choices= parameter in selectInput. The reason being, i need to use the values selected by user as an input for a function. I see names, ID, attr instead of values when I pass these arguments. Below is my code. Appreciate any help. Thank you
The server.r, lists the searchable fields in pubmed ( Eg:title, ALl fields, # UID etc). These list need to pop up for user UI, and when he selects his fields # of interest. The selection need to be passed to other function.
At this time, the code runs but does not give me the list of searchable fields and unable to pass any selection.
server.R
shinyServer(
function(input, output) {
output$Choose_Feild <- renderUI({
a = data.frame(entrez_db_searchable(db = "pubmed",
config = NULL))
unlist(a$FullName, use.names = FALSE)
}))
ui.R
shinyUI(
fluidPage(
titlePanel(title = "My data "),
sidebarLayout(
sidebarPanel(
h3("Enter values"),
selectInput( inputId = "var_y",label = "Field" , choices =
uiOutput("Choose_Feild") )))

You simply cannot use renderUI in such a way.
Since choices don't depend on any input you can pass choices directly:
library(shiny)
shinyUI(bootstrapPage(
selectInput(
inputId = "var_y", label = "Field" ,
choices = sapply(
rentrez::entrez_db_searchable(db = input$db, config = NULL),
function(x) x$FullName, USE.NAMES=FALSE
)
)
))
If you want to generate choices dynamically, for example based on another input you can use updateSelectInput:
server.R
shinyServer(function(input, output, session) {
observe({
choices <- sapply(
rentrez::entrez_db_searchable(db = input$db, config = NULL),
function(x) x$FullName, USE.NAMES=FALSE
)
updateSelectInput(session, "var_y", choices=choices)
})
})
ui.R
shinyUI(bootstrapPage(
selectInput(
inputId = "db", label="DB",
choices=c("pmc"="pmc", "pubmed"="pubmed")
),
selectInput(
inputId = "var_y", label = "Field" ,
choices = c()
)
))

Related

How does input from insertUI get stored?

I've created a SelectizeInput() UI using the insertUI() function. Essentially, I have an action button which adds a SelectizeInput() every time it's clicked. The idea is that the user selects columns from their data to put into groups. The creation of the UI works fine. I can also see in the Shiny trace that the selection works fine. However, I'm unsure how to access these variables to use in later plots. This is the code I have:
UI:
actionButton("cr_exp", "Create new biological group")
Server:
observeEvent(input$cr_exp, {
insertUI(
selector = "#cr_exp",
where = "afterEnd",
ui = selectizeInput(inputId = paste0("grp", input$cr_exp), label = "Select samples", choices = colnames(exp_dff()), options = list(create=TRUE), multiple=TRUE))
tags$div(id = paste0("grp", input$cr_exp))
})
In the shiny trace, it shows that the group is created, but I can't figure out how to access the value:
RECV {"method":"update","data":{"grp1":["MV4negControl01","MV4negControl02"]}}
You access the values just like any other input values: by the input element’s
id from the input reactive values:
library(shiny)
ui <- fluidPage(
actionButton("cr_exp", "Create new biological group"),
verbatimTextOutput("choices")
)
server <- function(input, output, session) {
observeEvent(input$cr_exp, {
insertUI(
selector = "#cr_exp",
where = "afterEnd",
ui = selectizeInput(
inputId = paste0("grp", input$cr_exp),
label = "Select samples",
choices = LETTERS,
options = list(create = TRUE),
multiple = TRUE
)
)
tags$div(id = paste0("grp", input$cr_exp))
})
output$choices <- renderPrint({
lapply(seq_len(input$cr_exp), function(i) input[[paste0("grp", i)]])
})
}
shinyApp(ui, server)

selectizeInput paramter 'multiple' unchangeable when updated server-side

I have a selectizeInput (with parameter multiple = FALSE) in a shiny app. I´m not able to change the multiple-parameter afterwards by using the server-side updateSelectizeInput() and setting the option there.
Here is an example:
library(shiny)
ui <- fluidPage(
selectizeInput(
inputId = "name",
label = "Select Name:",
choices = NULL
)
)
server <- function(input, output, session) {
updateSelectizeInput(
inputId = "name",
choices = c("Markus", "Lisa", "Peter"),
options = list(maxItems = 10),
server = TRUE # set consciously, I have a big list to handle
)
}
shinyApp(ui, server)
If I don´t set the server parameter to TRUE, everything works just fine. Is this a bug or do I miss something?
To select multiple items, you can set multiple=TRUE in the selectizeInput as shown below.
library(shiny)
ui <- fluidPage(
selectizeInput(
inputId = "name",
label = "Select Name:",
choices = NULL, multiple=T
)
)
server <- function(input, output, session) {
updateSelectizeInput(
inputId = "name",
choices = c("Markus", "Lisa", "Peter"),
options = list(maxItems = 10),
server = TRUE # set consciously, I have a big list to handle
)
}
shinyApp(ui, server)

R shiny favourites in long selectInput lists

How do I deal with long lists of options? In the example below, I have a subset of the options as favourites, but want to be able to select all options including the non-favourites. How do I get the input$selected to return what I selected last based on both the radiogroupbutton() and the selectInput()?
EDIT: I would like to keep the look, which has radiobuttons AND a drop down list. Therefore, I assume both will need different inputID's which then could be combined (somehow) in the server site (as Joris suggested). I am not sure how to combine them on the server site, and how to identify what was selected last.
ALL.options <- apply(expand.grid(LETTERS, LETTERS), 1, function(x){paste(x, collapse="")})
favourites <- sample(ALL.options, 20)
ui <- fluidPage(
h3("Favourites:"),
radioGroupButtons(inputId="selected",
choices = sort(favourites),
individual = TRUE,
selected = NULL,
width="20%"),
selectInput(inputId="selected", label = "Other options",
choices = ALL.options,
selected = NULL),
h3("THIS IS YOUR SELECTION:"),
verbatimTextOutput("choice")
)
)
server <- function(input, output) {
output$choice <- renderPrint(
input$selected
)
}
shinyApp(ui, server)
Perhaps it suffices to use a single selectInput or selectizeInput that lists the Favourites and Other options in separate option groups (see e.g. Shiny: Option groups for selectize input):
library(shiny)
ALL.options <- apply(expand.grid(LETTERS, LETTERS), 1, function(x){paste(x, collapse="")})
favourites <- sample(ALL.options, 20)
ui <- fluidPage(
selectizeInput(inputId = "selected", label = "All options", choices = list(
Favourites = favourites,
`Other options` = setdiff(ALL.options, favourites)
),
options = list(
placeholder = '<None selected>',
onInitialize = I('function() { this.setValue(""); }')
)
),
h3("THIS IS YOUR SELECTION:"),
verbatimTextOutput("choice")
)
server <- function(input, output) {
output$choice <- renderPrint({
validate(need(input$selected, "None selected"))
input$selected
})
}
shinyApp(ui, server)
NB: If you instead use two separate inputs (radioGroupButtons and selectInput) you could combine the selected choices server-side in a reactive object. For instance:
library(shiny)
library(shinyWidgets)
ALL.options <- apply(expand.grid(LETTERS, LETTERS), 1, function(x){paste(x, collapse="")})
favourites <- sample(ALL.options, 20)
ui <- fluidPage(
h3("Favourites:"),
radioGroupButtons(inputId = "radio",
choices = sort(favourites),
individual = TRUE,
selected = character(0),
width="20%"),
selectizeInput(inputId="select", label = "Other options",
choices = ALL.options,
options = list(
placeholder = '<None selected>',
onInitialize = I('function() { this.setValue(""); }')
)
),
h3("THIS IS YOUR SELECTION:"),
verbatimTextOutput("choice")
)
server <- function(input, output) {
## initialize reactive value
currentSelected <- reactiveVal(NULL)
## update based on radioGroupButtons
observeEvent(input$radio, {
currentSelected(input$radio)
})
## update based on selectInput
observeEvent(input$select, {
currentSelected(input$select)
})
output$choice <- renderPrint({
validate(need(currentSelected(), "None selected"))
currentSelected()
})
}
shinyApp(ui, server)
Created on 2019-06-17 by the reprex package (v0.3.0)
I am not sure if I understand fully what you are trying to achieve. I also notice that both the radioGroupButtons and the selectInput have the same inputId. If the idea is to print both the choices, you could change the inputId of the selectInput to say, select and just modify the renderPrint as:
output$choice <- renderPrint(
c(input$selected, input$select)
)
Is this what you are looking for?

Add items to the list of the selectInput by using button (RShiny)

I have the following code:
library(shiny)
vec <- seq(1,10)
ui <- fluidPage(
titlePanel(""),
sidebarLayout(
sidebarPanel(
fluidRow(
selectInput("selection", "Select number", vec, multiple = TRUE),
actionButton("First_fives", "First Fives" ),
actionButton("Last_fives", "Last Fives"),
actionButton("ok", "OK"))
),
mainPanel(
fluidRow(
h5("Selected numbers:")),
textOutput('num')
)
)
)
server <- function(input, output, session) {
observeEvent(input$First_fives,{
updateSelectInput(session, inputId = "selection", choices = vec[1:5])
})
observeEvent(input$Last_fives,{
updateSelectInput(session, inputId = "selection", choices = vec[6:10])
})
data <- reactiveValues()
observeEvent(input$ok,{
data$selected <- input$city
})
output$num <- renderText({data$selected})
}
shinyApp(ui = ui, server = server)
I almost managed to do what I want but not quite.
My selectInput box is empty when running the code and you can select amongst 10 items (from 1 to 10). This is fine.
Now I would like, when clicking on the button "First fives", the numbers 1 to 5 to be added to this empty box. In others words I would like to get the same as on the picture below in one click.
Please add selected on the updateSelectInput. The code will be like this:
observeEvent(input$First_fives,{
updateSelectInput(session, inputId = "selection", choices = vec[1:5],selected = vec[1:5])
})
observeEvent(input$Last_fives,{
updateSelectInput(session, inputId = "selection", choices = vec[6:10],selected = vec[6:10])
})
Please not I have only checked this function,not others.
Pls check if this meet your requirements.

R Shiny synchronize filters on multiple tabs

I built a R Shiny application with multiple tabs, which have some filters in common. Right now, all filters are stand-alone and do not synchronize across multiple tabs. Hence, when I change selectInput1 from value "a" to value "b", I have to repeat this handling on the next tab which contains selectInput2 with the same options/meaning.
I thought about making the filters dynamic, hence rendering them using the server side of R Shiny. Then of course, I can always make selectInput2 equal to selectInput1. But what if the user changes selectInput2 rather than selectInput1? It creates kind of a loop in the logic.
I spent quite some time finding a solution for this problem, and somehow I'm sure I'm not the first one encountering this problem. Suggestions or useful links would be really helpful!
Example:
## UI.R
shinyUI(
dashboardPage("Dashboard",
# Create tabs
tabPanel("Start",
p("This is the frontpage")
),
tabPanel("tab1",
uiOutput("selectInput1")
),
tabPanel("tab2",
uiOutput("selectInput2")
)
)
)
and:
## Server.R
library(shiny)
shinyServer(function(input, output,session){
output$selectInput1 <- renderUI({
selectInput(inputId = "id1",
label = "select",
choices = c("a","b","c"),
selected = "a")
})
output$selectInput2 <- renderUI({
selectInput(inputId = "id2",
label = "select",
choices = c("a","b","c"),
selected = "a")
})
})
I would personally use a single input control to control the different tab panels. One way is to include that single input under your tabs:
shinyApp(
fluidPage(
fluidRow(
tabsetPanel(
tabPanel("Tab1",
verbatimTextOutput("choice1")),
tabPanel("Tab2",
verbatimTextOutput("choice2"))
)
),
fluidRow(
selectInput("id1", "Pick something",
choices = c("a","b","c"),
selected = "a")
)
),
function(input, output, session){
output$choice1 <- renderPrint(input$id1)
output$choice2 <- renderPrint({
paste("The choice is:", input$id1)
})
}
)
Or, as you use a shinydashboard, you could actually add that control in the sidebar, possibly again in its own row under a set of tabs if you must.
I can't think of a reason to have multiple inputs who automatigically select the same thing. Other than slowing down your app, I can't see any gain. But if you insist, you make the selected choice a reactive value using reactiveVal and you use eg observeEvent() to update that reactive value. A small example using shinydashboard:
library(shinydashboard)
library(shiny)
ui <- shinyUI(
dashboardPage(title = "Dashboard",
dashboardHeader(),
dashboardSidebar(
tabsetPanel(
tabPanel("tab1",
uiOutput("selectInput1")
),
tabPanel("tab2",
uiOutput("selectInput2")
)
)),
dashboardBody(
verbatimTextOutput("selected")
)
)
)
server <- shinyServer(function(input, output,session){
thechoice <- reactiveVal("a")
output$selectInput1 <- renderUI({
selectInput(inputId = "id1",
label = "select",
choices = c("a","b","c"),
selected = thechoice())
})
output$selectInput2 <- renderUI({
selectInput(inputId = "id2",
label = "select",
choices = c("a","b","c"),
selected = thechoice())
})
observeEvent(input$id2,{
thechoice(input$id2)
})
observeEvent(input$id1,{
thechoice(input$id1)
})
output$selected <- renderPrint({
c(input$id1, input$id2)
})
})
shinyApp(ui, server)

Resources