44

I have some data below that I'm using to create a donut chart in R shiny, where date is a character. I want to be able to select the email whose score I want to view, but then in the second dropdown selection only see the dates for which that email has activity.

For example, if I select email = xxxx in the first dropdown, I want to see only 'no activity' in the date selection field. And for email = yyyy, I want to see only 6/17/14, 6/18/14, 6/19/14 as selections.

I've tried a sort of nested subsetting in the ui. Example:

> ui <- shinyUI(fluidPage(
+   sidebarLayout(
+     sidebarPanel(
+       selectInput('Select', 'Customer:', choices = unique(as.character(dat5$email))),
+       selectInput("User", "Date:", choices = dat5[dat5$email==input$Select,date])
+     ),
+     mainPanel(plotOutput("distPlot"))
+   )
+ ))

But this still shows all possible date selections

DATA

email   date        variable    value   ymin    ymax
xxxx    no activity e_score         0   0       0
xxxx    no activity diff            1   0       1
yyyy    6/17/14     e_score    0.7472   0       0.7472
yyyy    6/17/14     diff       0.2528   0.7472  1
yyyy    6/18/14     e_score    0.373    0       0.373
yyyy    6/18/14     diff       0.627    0.373   1
yyyy    6/19/14     e_score    0.533    0       0.533
yyyy    6/19/14     diff       0.467    0.533   1

My code so far:

app.R

library(shiny)
library(shinydashboard)

ui <- shinyUI(fluidPage(
  sidebarLayout(
    sidebarPanel(
      selectInput('Select', 'Customer:', choices = unique(as.character(dat5$email))),
      selectInput("User", "Date:", choices = unique(dat5$date) )
    ),
    mainPanel(plotOutput("distPlot"))
  )
))


server <- function(input, output) {
  output$distPlot <- renderPlot({
    ggplot(data = subset(dat5, (email %in% input$Select & date %in% input$User)), aes(fill=variable, ymax = ymax, ymin = ymin, xmax = 4, xmin = 3)) +
      geom_rect(colour = "grey30", show_guide = F) +
      coord_polar(theta = "y") +
      geom_text(aes(x = 0, y = 0,label = round(value[1]*100))) +
      xlim(c(0, 4)) +
      theme_bw() +
      theme(panel.grid=element_blank()) +
      theme(axis.text=element_blank()) +
      theme(axis.ticks=element_blank()) +
      xlab("") +
      ylab("") +
      scale_fill_manual(values=c('#33FF00','#CCCCCC')) 

  })
}
  shinyApp(ui = ui, server = server)
Uwe Keim
  • 39,551
  • 56
  • 175
  • 291
Hillary
  • 785
  • 1
  • 6
  • 17

2 Answers2

44

You can't access inputs in the ui.R part of the app so you need to use renderUi/uiOutput to dynamically generate your selectInput.

In your ui.R you could add:

uiOutput("secondSelection")

and in your server.R:

 output$secondSelection <- renderUI({
                selectInput("User", "Date:", choices = as.character(dat5[dat5$email==input$Select,"date"]))
        })
NicE
  • 21,165
  • 3
  • 51
  • 68
  • That did it!! For some reason, I had to `choices = as.character(dat5[dat5$email==input$Select,"date"])` without the quotes around date. Otherwise worked great! – Hillary Jan 21 '16 at 18:15
  • 2
    I'm confused by the answer statement "you can't access inputs in the ui.R part of the app". When you use conditional panel you are defining condition based on input.panel. Isn't this depending on an input of the UI? – Giacomo Sep 26 '17 at 13:22
  • this works for me (except I'm using `selectizeInput`) with only pretty small datasets. With bigger, the dynamic menu field and text box turn grey and then Shiny becomes unresponsive. curious if any one has any suggestions for a different approach, when there are quite a few choices to be discovered? – dbo Apr 17 '19 at 18:49
  • NicE, how would you update the 'User' input? – Caetano Almeida e Brito Jan 18 '23 at 16:10
16

You can also do it without changing ui.R. Adding this to server.R has the same effect.

    observe({
          updateSelectInput(session, "User", choices = as.character(dat5[dat5$email==input$Select, date]))
    })

Though it is a useful and powerful tool, I find it "cleaner" to get by without renderUI. It keeps the UI in the UI and the server in the server. But that is just a matter of taste, I suppose.

Jan
  • 4,974
  • 3
  • 26
  • 43
  • 1
    As Apps get larger and more complicated, I've been warned repeatedly about using renderUI as it tends to slow things down and can cause other issues. I would use Jan's solution. – Curious Jorge - user9788072 Mar 02 '23 at 12:15