Hi currently I've got a sample data set like this
df<- data.frame(site = c('A1', 'A1', 'A1', 'B1', 'B1','B1','B1','C1','C1'),
part = c('a1', 'a1', 'a2', 'b1', 'b1', 'b2','b3','c1','c2'),
value = c(2,3,4,5,6,7,8,9,10))
> df
site part value
A1 a1 2
A1 a1 3
A1 a2 4
B1 b1 5
B1 b1 6
B1 b2 7
B1 b3 8
C1 c1 9
C1 c2 10
I would like to put a side bar in shiny user interface with two select boxes. One is "choose" site and the other one is "part".
shinyUI(
fluidPage(
titlePanel("Choose Site, part"),
sidebarLayout(
sidebarPanel(
selectInput("select_site", label = "Select Site",
choices = unique(df$site),
selected = unique(df$site)[1]),
selectInput("select_part", label = "Select Part",
choices = unique(df$part),
selected = unique(df$part)[1])
),
mainPanel(
plotOutput("example")
)
)
)
)
The objective is when I choose A1 in "select_site", I can only choose a1 or a2 in "select_part". However this code right now can choose a1, a2, b1, b2, b3, c1, c2 in "select_part" no matter how I choose in "select_site".
In the real data set there are a lot more sites and parts than this example so I'm looking for a generic way to identify the parts within each site rather than type in the names myself.
Can anyone help me with some modification of this code?
Thanks in advance
You should look at updateSelectInput
instead of conditionalPanel
.
What conditionalPanel
does is to hide some UI elements completely, instead of hiding some options in a selectInput
.
In your case, you can create an observer in server.R
that watches for the selection made by the user for select_site
.
shinyUI(
fluidPage(
titlePanel("Choose Site, part"),
sidebarLayout(
sidebarPanel(
selectInput("select_site", label = "Select Site",
choices = list("A1"="A1", "B1"="B1", "C1"="C1"),
selected = "A1"),
selectInput("select_part", label = "Select Part",
choices = NULL,
selected = NULL) # empty for now, will be updated in server.R
),
mainPanel(
plotOutput("example")
)
)
)
)
Now create a global.R
to share the df
object with both ui.R
and server.R
.
df <- data.frame(site = c('A1', 'A1', 'A1', 'B1', 'B1','B1','B1','C1','C1'),
part = c('a1', 'a1', 'a2', 'b1', 'b1', 'b2','b3','c1','c2'),
value = c(2,3,4,5,6,7,8,9,10))
site_choices <- as.list(df$site)
names(site_choices) <- df$site
Finally, at the server side, use an observer to update the select_part
's options when the selection of select_site
changes.
library(shiny)
shinyServer(function(input, output, session){
observe({
if (input$select_site != "") {
part_choices <- as.list(df$part[df$site == input$select_site])
names(part_choices) <- df$part[df$site == input$select_site]
updateSelectInput(session, "select_part", choices=part_choices)
}
})
})
You can make use of conditionalPanel
, if you have other site-specific elements that you only want to display conditionally.
For example, if site A1
has some very specific input controls or output elements that do not exist in other sites, you can wrap those input/output elements in a condtionalPanel
with the condition parameter: condition="input.select_site == 'A1'"
. (Note that you use .
here instead of $
because this condition is evaluated in your browser by Javascript, not in Shiny by R. )
Then, once the user switches to other sites, those elements in the conditionalPanel
will disappear. (More interestingly, output elements that are hidden won't be updated even if their dependent inputs change. Because it make little sense to update something that is invisible to the user.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With