0
votes

Hello

I'm having some trouble with an error 'aesthetics must be either length 1 or the same as the data' for a reactive ggplot in a shiny.

First, a little bit of info on the structure of the data:

I'm using a big dataset, with lots of variables. As seen in the code below, I've built a reactive dataset to first filter by geography (higher and lower levels) and service type. The user then has the option to choose a Y variable using a radioButton input. In the example given below, the Services variable is the total number of commercial services being run by brands in the area, whereas the Brand variable is a list of Brands operating in that locality. As an example:

"Brand"     "Services"    "Rating"
  A         25            Good
  B         12            Good 
  C         45            Poor
  ...       ...           ...

I'm want my Y variable made changeable according to a radioButton input. There are two possible variables, one is numerical (i.e. 'Services' or number of services) and the other is categorical (i.e. commercial brands). Both vectors are the same length. In sum, I want the Y axis to show a count of either variables (i.e. No. Services or No. Brands).

However, when I change the radioButton selection, the visual does not update and (as seen in the images 1 and 2 below) the Y axis does not format properly.

What am I missing?

Image 1: Selected Services enter image description here

Image 2: Selected Brands enter image description here

UI

ui <- fluidPage(
   titlePanel("Test App"),
   sidebarLayout(
      sidebarPanel(id = "sidebar",
                   uiOutput("geography1"),
                   uiOutput("geography2"),
                   uiOutput("service"),
                   radioButtons("y", "Choose Y variable",
                                c("Services",
                                  "Brands"),
                                selected = "Services")
      )
         mainPanel(
            tabsetPanel(type = "tabs",
                        tabPanel("Visual", plotOutput("plot", height = "500px")),
                        tabPanel("Underlying data", dataTableOutput("table"))
         )
      )
   )
   )
)

Server

server <- function(input, output) {

   output$geography1 = renderUI({
      selectInput(inputId = "geog1",
                  label = "Select geography (higher):", 
                  choices = as.character(unique(Test$Geog1)),
                  selected = "Region")
   })
   datasub <- reactive({
      req(input$geog1)
      filter(Test, Geog1 %in% input$geog1)
   })

   output$geography2 = renderUI({
      selectInput(inputId = "geog2", 
                  label = "Select geography (lower):", 
                  choices = unique(datasub()[,"Geog2"]),
                  selected = unique(datasub()[,"Geog2"])[1]) 
   })
   datasub2 <- reactive({
      req(input$geog2)
      filter(datasub(), Geog2 %in% input$geog2)
   })

   output$service = renderUI({
      selectInput(inputId = "service",
                  label = "Select Service Type:",
                  choices = unique(datasub2()[,"Sub_type"]),
                  selected = unique(datasub2()[,"Sub_type"])[1])
   })
   datasub3 <- reactive({
      req(input$geog2)
      filter(datasub2(), Sub_type %in% input$service)

   })

   y <- switch(input$y, 
               "Services" = datasub3()$Services,
               "Brands" = datasub3()$Brands)

   # Plot
   output$plot = renderPlot({

      ggplot(datasub3(), aes(x = Overall_rating, y = input$y, fill = Overall_rating))+
         geom_bar(stat = "identity")+
 scale_fill_manual(name = "Overall Service Rating", values = colours)

   })

   # Generate an data table view of the data ----
   output$table <- renderDataTable({
      datasub3()[,1:9]
   }) 

      shinyApp(ui, server)  

Image 3: Example of Desired Outcome enter image description here

1
In ggplot try aes_string(x="Overall_rating", y=as.character(input$y), fill= "Overall_rating") - A. Suliman
Unfortunately doesn't work, the code returns: "Object Overall_rating not found". - Pryore
Can you please provide reproducible data set - A. Suliman
You are missing some parenthesis/brackets. Could you please make sure that your code is running properly? - Ozan147
@A.Suliman I can only provide you with a sample dataset. Is this okay? Sample_data <- data.frame( Geog1 = c("Region","Region","Region","Region","Region","Region"), Geog2 = c("North West","North West","North West","North West","North West","North West"), Service_type = c("Shops","Shops","Shops","Shops","Shops","Shops"), Services = c(45,25,25,15,40,23), Brands = c("Brand A","Brand B","Brand C","Brand D","Brand E","Brand F"), Overall_rating = c("Good","Good","Poor","Okay","Very Poor","Okay","Unrated") ) - Pryore

1 Answers

1
votes

The problem was switch, which should define as below inside a reactive expression

y <- reactive(switch(input$y, 
                "Services" = datasub3()$Services,
                "Brands" = datasub3()$Brands))

ggplot call will be

ggplot(datasub3(), aes(x = Overall_rating, y = y(), fill = Overall_rating))

Provided data set does not include Sub_type variable, hence I work with datasub2(). But if you counter any issues let me know.

Update

  ggplot(datasub3(), aes(x = Overall_rating, y =y(), fill = Overall_rating))+
  geom_bar(stat = "identity") + 
  scale_fill_manual(name = "Overall Service Rating", values = colours) +
  geom_text(aes(label=Services), angle=00, hjust= 0.5, vjust=-1, cex=5)