Averysaurus
Averysaurus

Reputation: 31

Shiny: how to use checkBoxGroupInput() to reactively change a bar chart

I'm pretty new to shiny and am struggling on how to use check boxes to update values in a bar chart. The idea I'm after is when a user ticks on a check box, a numerical value is generated that will be added to an aggregate from other inputs to make a bar chart. Here is the code I have gotten to work so far:

library(shiny)
ui <- fluidPage(

titlePanel("TCO Calculator"),
  
mainPanel(
    
    sidebarPanel(
        helpText("Product 1 information:"),
        numericInput(
            inputId = "price_1",
            label = "Purchase Price",
            value = "0",
            min = 0,
            width = '50%'
        ),
        numericInput(
            inputId = "install_1",
            label = "Installation cost",
            value = "0",
            min = 0,
            width = '50%'
        ),
        
        selectInput("disposal_1", "Disposal Cost",
                    choices = list(Buyback = (10),
                                   Dump = (30),
                                   Reuse = (5)),
                    width = '50%'),
        
        checkboxGroupInput("maint_1", "Maintenance:",
                           choices = c("Waxing", 
                        "Stripping", "Burnishing"),
                           selected = NULL)
        ),
    
    
    sidebarPanel(
        helpText("Product 2 information:"),
        numericInput(
            inputId = "price_2",
            label = "Purchase Price",
            value = "0",
            min = 0,
            width = '50%'
        ),
        numericInput(
            inputId = "install_2",
            label = "Installation cost",
            value = "0",
            min = 0,
            width = '50%'
        ),
        # make list? 
        selectInput("disposal_2", "Disposal Cost",
                    choices = list(Buyback = (10),
                                   Dump = (30),
                                   Reuse = (5)),
                    width = '50%'),
        
        checkboxGroupInput("maint_2", "Maintenance:",
                           choices = NULL, 
                           selected = NULL,
                           inline = FALSE,
                           width = NULL, 
                           choiceNames = c("Waxing", 
                                           "Stripping", "Burnishing"),
                           choiceValues = c(10, 20, 40))

         
    ),
         plotOutput("costPlot")))

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

# aggregate inputs into reactive bar chart values. 
select_price <- reactive({
    
    c(input$price_1 + input$install_1 
      + as.numeric(input$disposal_1),
      
      input$price_2 + input$install_2 + 
          as.numeric(input$disposal_2))
})
# Bar chart.
my_bar <- output$costPlot <- renderPlot({
    barplot(select_price(), 
            beside = T,
            border=F, 
            las=2 , 
            col=c(rgb(0.3,0.1,0.4,0.6) , 
                  rgb(0.3,0.5,0.4,0.6)) , 
            space = 3,
            ylab = "Total cost per square foot, US Dollar")
    
    abline(v=c(4.9 , 6.1) , col="grey")
    
    legend("top", legend = c("Product 1", "Product 2" ), 
           col = c(rgb(0.3,0.1,0.4,0.6), 
                   rgb(0.3,0.5,0.4,0.6)), 
           bty = "n",
           pch=20 , pt.cex = 4, 
           cex = 1.6, horiz = FALSE, 
           inset = c(0.05, 0.05))
    
    my_bar      
})
}

shinyApp(ui = ui, server = server)

I've been successful with the numericInput and selectInput stuff so far, I am having trouble putting together a concise way to include check boxes (with corresponding numeric values) into a reactive function that I can path into select_price(), like I have done with the numeric and selectBox stuff. Things go sideways when I try to map from other examples. I feel like there is an elegant, or in least working solution that exists. Any insight towards how to solve this would be so appreciated, thanks!

Upvotes: 1

Views: 201

Answers (1)

Thomas
Thomas

Reputation: 1302

I am not sure whether this entirely solves all your problems but try this:

  • For maint_2, you correctly separate choiceNames and choiceValues. For maint_1 you dont't
checkboxGroupInput("maint_1", "Maintenance:",
                   choices = NULL,
                   selected = NULL,
                   choiceNames = c("Waxing", "Stripping", "Burnishing"),
                   choiceValues = c(10, 20, 40))
  • Then you can add input$maint_1 and input$maint_2 to your reactive (also wrapped in as.numeric(). I also use sum for + as you don't have a default for input$maint_1 and input$maint_2. sum evaluates this to 0 while + throws an error.
select_price <- reactive({
    
  c(sum(input$price_1, input$install_1, as.numeric(input$disposal_1), as.numeric(input$maint_1)),
      
    sum(input$price_2, input$install_2, as.numeric(input$disposal_2), as.numeric(input$maint_1)))
})

Upvotes: 1

Related Questions