5

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)
3
  • 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. Commented Jul 10, 2016 at 8:19
  • if I recall correctly you should use print() when using ggplot2. So... print(ggplot(C2()...) or p1 <- ggplot(C2()...) print(p1) Commented Jul 10, 2016 at 8:22
  • @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. Commented Jul 10, 2016 at 13:35

2 Answers 2

4

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.

Sign up to request clarification or add additional context in comments.

2 Comments

To make debuging easier you can also define an observer in which you'll print out inputs and/or results of the manipulation of inputs. For instance: observe({ print(levels(input$Demog)) })
Thank you. I am learning a lot from these answers. I will attempt the debug suggestion you gave above. I appreciate it and I will let you know if that helps me get to the right solution.
1

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.

4 Comments

Thank you rosscova. I am sort of new to real programming so it never occurred to me that this could be a scoping issue ( I have just started reading about this). It did not work when I moved the code just below library(dplyr) but your logic makes sense and I will leave it there. I will use an example dataset as suggested by you and @Mikael. If I can not resolve in the next couple of hours I will repost with example dataset.
No worries, let us know how you go.
I did. What's next? All the advice I received helped some what. Do I need to do something else on the site? Let me know. thanks
It's a good idea to mark the answer that helped you as accepted, that way others will find the most useful answer more easily when they're searching. If you resolved the issue yourself, you can also post your own answer, and accept that. Either way, try to provide a resolution; your post may be useful for others having the same issue. That's what SO is all about :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.