Sean
Sean

Reputation: 67

creating a barplot with shiny that shows a new plot each time a region is selected

I am trying to create an interactive bar plot , however my skills on shiny are not the best. I have attempted to get something working but I am struggling - the server section starts to confuse me a bit.

Below are the sets of user inputs I am trying to include in the interactive plot:

  1. A select input that allows you to select a region, and when this selection is made an entirely new plot appears (showing the demographics for that particular region only).

  2. A slider input that allows you to slide across a range of age groups. For example - you may only want to select a range of the ages from '0 to 10' and '40 to 44'.

Below I have created a reproducible example that you can copy and paste. Please note the age ranges in my main dataset are not at equal intervals, nor is there enough data so that every location has a full set of age ranges. All i have done is try create a small version of a larger dataset I have.


library(dplyr)
library(ggplot2)
library(shiny)
library(shinyWidgets)

# creating example data

exampledata <- data.frame(City=c("London","Liverpool","Manchester",
                                        "Porstmouth","Liverpool","Leeds",
                                        "London","Manchester","Nottingham"),
                         Ageband = c("35 to 39","80+","40 to 44",
                                        "0 to 10","80+","35 to 39",
                                        "40 to 44","0 to 10", "80+"),
                         count = c(1200,800,520,
                                      300,105,630,
                                      410,150,700))


# Static Plot to show what I intend to make interactive

ggplot(exampledata, aes(fill=Ageband, y=count, x=Ageband)) + 
  geom_bar(position="dodge", stat="identity", show.legend = FALSE) +
  facet_wrap(~City)+
  labs(y="Participant count", x=" ",caption=(paste0("Participants sampled = ", sum(exampledata$count))))+
  scale_fill_manual(name="Age",values=c("#CEE0F1", "#C3DAEE" ,"#B3D3E8" ,"#A2CBE2", "#8FC1DD" ,"#79B6D9" ,"#66AAD4" ,"#559FCD" ,"#4493C6", "#3686C0", "#2878B9","#1C69AF" ,"#1257A1" ,"#084594", "#05337d"))+
  theme(plot.title = element_text(hjust = 0.5))+
  theme(axis.text.x = element_text(angle = 90))

# shiny attempt

ui <- fluidPage(
  titlePanel("Age Distribution of Research"),
  selectInput("location", "Select Location", choices = exampledata$City),
  sliderTextInput("age", "Select Age", choices = exampledata$Ageband)
  plotOutput("bar")
)

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

# At this point would you need to create a reactive expression or not?
  
  data <- reactive({
    exampledata %>%
      filter(City == input$City)
  })

# At which point of the plots do the inputs need specifying? 
  
  output$plot <- renderPlot({
    
    ggplot(data, aes(aes(fill=Ageband, y=count, x=input$age)) + 
             geom_bar(position="dodge", stat="identity", show.legend = FALSE)
   })
}

}

shinyApp(ui = ui, server = server)



Upvotes: 0

Views: 1035

Answers (1)

Limey
Limey

Reputation: 12586

Does this come close to what you want?

library(dplyr)
library(ggplot2)
library(shiny)
library(shinyWidgets)

exampledata <- data.frame(City=c("London","Liverpool","Manchester",
                                 "Porstmouth","Liverpool","Leeds",
                                 "London","Manchester","Nottingham"),
                          Ageband = c("35 to 39","80+","40 to 44",
                                      "0 to 10","80+","35 to 39",
                                      "40 to 44","0 to 10", "80+"),
                          count = c(1200,800,520,
                                    300,105,630,
                                    410,150,700))

ui <- fluidPage(
  titlePanel("Age Distribution of Research"),
  selectInput("location", "Select Location", choices = exampledata$City, selected="London", multiple=TRUE),
  # Slider inputs work with numeric data, not categorical data
  selectInput("age", "Select Age", choices = exampledata$Ageband, selected="35 to 39", multiple=TRUE),
  plotOutput("plot")
)

server <- function(input, output, session) {
  data <- reactive({
    exampledata %>%
      filter(
        City %in% input$location,
        Ageband %in% input$age
      )
  })
  
  output$plot <- renderPlot({
    req(input$age, input$location)
    
    data() %>% 
      ggplot(aes(fill=City, y=count, x=Ageband)) + 
             geom_bar(position="dodge", stat="identity")
  })
}

shinyApp(ui = ui, server = server)

Upvotes: 1

Related Questions