5
votes

I have spent several hours trying to figure out how to generate a bar plot using ggplot2 for a shiny app I want to create. The ui works fine, however; the server function generates an empty plot.

The issue is with renderPlot function. I believe I must not be passing the reactive values properly to the aes_string arguments in ggplot. C2 is a filtered dataset. The goal is to build a simple app in which the user selects a two variables, a dataset is filtered based upon those variables. The subsetted dataset is passed to ggplot data argument.

       library(shiny)
library(dplyr)


ui <- fluidPage(
  sidebarLayout(
    sidebarPanel(
      selectInput(inputId = "Demog",label = "Factor:",choices = c("HH Income" = "Income",
                                                                  "Age Group" = "Age",
                                                                  "US Region" = "Region") , selected = "Age"),
      selectInput(inputId = "Car",label = "VW Model:",choices = c("BEETLE" = "BEETLE",
                                                                  "CC" = "CC",
                                                                  "EOS" = "EOS",
                                                                  "GOLF" = "GOLF",
                                                                  "GTI" ="GOLF SPORTSWAGEN GTI",
                                                                  "JETTA" = "JETTA",
                                                                  "PASSAT" = "PASSAT",
                                                                  "TIGUAN" = "TIGUAN",
                                                                  "TOUAREG" = "TOUAREG") , selected = "BEETLE"),
      radioButtons(inputId = "Metric",label ="Measurement Type",choices = 
                     c("Conquest Volume Index" = "TotCmpConqVol_IDX","C/D Ratio" = "TotCmpCDRatio_IDX"), selected = "TotCmpConqVol_IDX" )                

    )
  ),
  mainPanel(
    tags$h1("The Bar Charts"),
    tags$h2("The metrics"),


    plotOutput("P1")

  )

)
server <- function(input, output){
  library(ggplot2)
  CONQDF <- read.csv("C:/Users/Reginald/Desktop/CONQ_VW/CONQUEST2.csv")

  C2 <- reactive(subset(CONQDF,input$Demog %in% levels(input$Demog)[1] & CONQDF$VW_Model == input$Car))

  output$P1 <- renderPlot({
    ggplot(C2(),aes_string(x="CompMake", y=input$Metric))+ geom_bar(stat = "identity")
                          })
}






shinyApp(ui,server)
2
Welcome to stackoverflow! You could use as example dataset for example car dataset and change choices accordingly, then code would be reproducible and you would get faster answer. - Mikael Jumppanen
if I recall correctly you should use print() when using ggplot2. So... print(ggplot(C2()...) or p1 <- ggplot(C2()...) print(p1) - Mikael Jumppanen
@Mikael Jumppanen Thank you Mikael. I tried those options and still no luck. I thank you for the fast response and I will use one of the example datasets to see if I can get the code to run. If not, I will repost my response with the example dataset. I really appreciate it. - RareAir

2 Answers

4
votes

The ui works fine, however; the server function generates an empty plot.

This is most likely due to the fact that the function subset returns an empty dataset. In order to debug the code, first, I would print out in the console this part:

C2 <- reactive(subset(CONQDF,input$Demog %in% levels(input$Demog)[1] & CONQDF$VW_Model == input$Car))

I believe that this part is wrong because input$Demog is just a character string and not a factor. That's why levels(input$Demog) = NULL and input$Demog %in% levels(input$Demog) = FALSE. Hence, as a result, you get an empty dataset.

To check this:

output$P1 <- renderPlot({
    print(C2()) # print it out to the console.
    ggplot(C2(),aes_string(x="CompMake", y=input$Metric))+ geom_bar(stat = "identity")
})

If this is the case, you only need to re-think subsetting part.

1
votes

It looks like your C2 function can't see CONQDF (hence the blank plot). You can add () after CONQDF in your C2 call to run that read.csv every time, but you're probably better off moving the read.csv outside your server function altogether.

So move this line

CONQDF <- read.csv("C:/Users/Reginald/Desktop/CONQ_VW/CONQUEST2.csv")

to the top of your script, just below library(dplyr). This will make shiny read that file when the page first loads, instead of every time the input is updated, and will also place the resulting dataframe into the global environment, which will mean your C2 <- call will be able to see it.

I can't easily reproduce your app, so I can't test my answer. Please let me know whether or not it helps.