Output AUTOMATICALLY GETTING MIXED UP BY SHINY

rstudio

#1

I want to have the output of slider changing when the user drags while a particular feature is selected. When the user switches from the current feature to any other feature - the latest value of the slider should be displayed on the output space. BUT HERE IS THE WEIRD PROBLEM I AM FACING.

I am trying to do the above with the first two features - Feature1 and Feature2.
PROBLEM AREA - PLEASE SEE output$textFE and output$textVIS.

My desire - When I have if and else if conditions till 70 (in output$textVIS) then I get what I want. BUT AS SOON AS I INCLUDE THE else if command till 80 (JUST SOME EXTRA 4 lines with everything being the same), then the output goes crazy and I see TWO OUTPUTS BEING DISPLAYED AT PARALLEL which I DON"T WANT.

I have lost my hair thinking what is wrong with the code but at the end I have arrived at the conclusion that something is wrong with the SHINY PACKAGE - RSTUDIO in general.

PLEASE prove me wrong by sharing your valuable insights. I AM DEVASTATED.

Here is the ui.R
library(shiny)
library(shinydashboard)

shinyUI(
fluidPage(

# Creating the notifications at the center of the page instead of bottom right corner
tags$head(
  tags$style(
    HTML(".shiny-notification {
         position:fixed;
         top: calc(50%);;
         left: calc(50%);;
         width: 425px ;;
         font-size: 24px ;;
         }
         "
    )
    )
    ),
dashboardPage(
  dashboardHeader(title = "Feature Dependency", titleWidth = 400),
  dashboardSidebar(
    
                 
    
    box(
      
      h6("", textOutput("errorMessage")),
      #Creating the navy blue box and puttig background color of navy,
      width = 400, height = 350, background = "navy",
      
      
      #Increasing font size of radio buttons
      tags$style(type = "text/css", "label { font-size: 16px; }"),
      
      
      # First ask which feature/bar should be modified
      radioButtons("feature", "Modify", 
                   choices = c("Feature1", " Feature2", " Feature3", " Feature4", 
                               " Feature5", "Feature6", " Feature7", 
                               " Feature8", " Feature9", " Feature10"),
                   selected = NULL)
    ),
    
    box (
      
      # Then specify by what amount
      sliderInput("slider", "WEIGHT", 0, 100, value = 0, step = 5),
      align = "center", width = 400, background = "navy"
      ), #Box for slider Input ends here
      
      box (
        
      # Apply changes
      actionButton("go", "Apply changes"),
      
      br(),
      actionButton("reset", "Reset"),
      
      align = "center", width = 400, background = "navy"
      
    ), width = 400 #(this is the width for the whle sidebar)
       ), #sideBar ends here
  
  dashboardBody( 
    
    #fluidRow so that as the size of window changes the contents change
    fluidRow(
      
      mainPanel(
        
        #Making teh mainPanel which consists of 12 columns to soan the full length of window
        width = 12,
        
        #Box so that the graph could be accurately resized whenever wanted   
        box( height = 600, width = 1200, align = "center",
             
             plotOutput("bar_plot", 
                        #Increasing the size of output graph so that it looks good visually
                        height = 500)
          ), #Box for the main graph ends here
       
            box (
              column (1, 

                      align = "center",  infoBoxOutput("recordofchanges")  

              ),#1st column of nothing
                 column (2, 
                              align = "center",
                              h5("Feature1"),   verbatimTextOutput("textFE"),
                              h5("Feature2"),   verbatimTextOutput("textVIS")
                           
                 ),#2nd column ends here
        
                    column (2, 
              
                          
                               align = "center", 
                               h5("Feature3"),   verbatimTextOutput("textDPOS"),
                               h5("Feature4"),    verbatimTextOutput("textM")
    
                             ), #3rd column ends here
        
        
          
           
                   column (2, 
                
                
                               align = "center",
                                
                                h5("Feature5"),    verbatimTextOutput("textRIC"),
                                h5("Feature6"),    verbatimTextOutput("textDRI")
                                ), #4th column ends here
        
        
              
                      column (2, 
                
                              align = "center", 
                
                              h5("Feature7"), verbatimTextOutput("textRC"), 
                              h5("Feature8"),    verbatimTextOutput("textCS")

                        ), #5th column ends here
    
        
            
                        column (2, 
                
                
                             align = "center", 
      
                             h5("Feature9"),    verbatimTextOutput("textQI"),
                             h5("Feature10"),    verbatimTextOutput("textREL")
                          
                           ),#6th column ends here
                 
                       column (1, 
                         
                         
                          align = "center", 
                         
                            h5("Number of clicks"),   textOutput("clickCount")
                         
                          ),#7th column ends here
          align = "center", width = 1000  )# Box for current values of features end here
     
      )#mainPanel ends here
    )#fluidRow ends here
  )
)
    )
)

Here is the server.R
library(shiny)
library(shinydashboard)

shinyServer(function(input,output)
{

Create a dynamic vector with 4 elements. Each one corresponds to the

length to the bar: (I called it “L” so that I don’t have to type much :slight_smile: )

L <- reactiveValues(vec = c(“Feature1” = 100, " Feature2" = 100,
" Feature3" = 100, " Feature4" = 100,
" Feature5" = 100, " Feature6" = 100,
" Feature7" = 100, " Feature8" = 100,
" Feature9" = 100, " Feature10" = 100))

observeEvent(input$go, {
# After the button is pressed input$checkbox gives either

cat("\n")

print(paste0("Changing radioButtons to: ", input$feature))

# and input$slider gives
print(paste0("Changing the value of the slider to: ", input$slider))

# So basically we can use again observeEvent to modify the 
# dynamic matrix which will be then passed to barplot function

})

observeEvent(input$go, {
cat("\nChanging values of the dynamic matrix\n")

# Every time you press the button, the matrix will be modified.
# (In this way we avoid simultaneous dependency on 4 different inputs)

# To modify the matrix we can use if-statements

slider <- input$slider

if (input$feature == " Feature1") {
  
  #EXTRA CONDITION that prevents the other features from being negative while this feature is moved
  #The number 230 is found manually through trial error beyond which one of the features become negative
  if (L$vec["Feature1"] > 230) {
    output$errorMessage <- renderText({
      paste("You cannot increase further")
    })
    
  }
  else {
    
    L$vec[1] <- L$vec[1] + slider * 0.975
    L$vec[2] <- L$vec[2] - slider * 0.731
    L$vec[3] <- L$vec[3] - slider * 0.523
    L$vec[4] <- L$vec[4] - slider * 0.370
    L$vec[5] <- L$vec[5] - slider * 0.258
    L$vec[6] <- L$vec[6] - slider * 0.180
    L$vec[7] <- L$vec[7] - slider * 0.125
    L$vec[8] <- L$vec[8] - slider * 0.088
    L$vec[9] <- L$vec[9] - slider * 0.064
    L$vec[10] <- L$vec[10] - slider * 0.047
    
    # Creating The notifications for the feature metrics
    if (L$vec["Feature1"] > 210.5 & L$vec["Feature1"] < 226) {
      showNotification("Feature1is * AMONG THE BEST *", duration = 10, closeButton = TRUE,
                       type ="warning")
    }
    if (L$vec["Feature1"] > 226.55) {
      showNotification("Feature1 is * BEST IN CLASS *", duration = 10, closeButton = TRUE,
                       type ="message")
    }
    
  }
  
} else if (input$feature == " Feature2") {
  
  #EXTRA CONDITION that prevents the other features from being negative while this feature is moved
  #The number 175 is found manually through trial error beyond which one of the features become negative
  if (L$vec["Feature2"] > 173) {
    output$errorMessage <- renderText({
      paste("You cannot increase further")
    })
    
  } else {
    
    L$vec[1] <- L$vec[1] - slider * 0.975
    L$vec[2] <- L$vec[2] + slider * 0.731
    L$vec[3] <- L$vec[3] - slider * 0.523
    L$vec[4] <- L$vec[4] - slider * 0.370
    L$vec[5] <- L$vec[5] - slider * 0.258
    L$vec[6] <- L$vec[6] - slider * 0.180
    L$vec[7] <- L$vec[7] - slider * 0.125
    L$vec[8] <- L$vec[8] - slider * 0.088
    L$vec[9] <- L$vec[9] - slider * 0.064
    L$vec[10] <- L$vec[10] - slider * 0.047
    
    # Creating The notifications for the feature metrics
    if (L$vec["Feature2"] > 164.4 & L$vec["Feature2"] < 172) {
      showNotification("Feature2  is * AMONG THE BEST *", duration = 10, closeButton = TRUE,
                       type ="warning")
    }
    if (L$vec["Feature2"] > 172.375) {
      showNotification("Feature2 is * BEST IN CLASS *", duration = 10, closeButton = TRUE,
                       type ="message")
    }
    
    
  }
  
} else if (input$feature == " Feature3") {
  
  #EXTRA CONDITION that prevents the other features from being negative while this feature is moved
  #The number 154 is found manually through trial error beyond which one of the features become negative
  if (L$vec["Feature3"] > 152) {
    output$errorMessage <- renderText({
      paste("You cannot increase further")
    })
  } else {
    
    L$vec[1] <- L$vec[1] - slider * 0.975
    L$vec[2] <- L$vec[2] - slider * 0.731
    L$vec[3] <- L$vec[3] + slider * 0.523
    L$vec[4] <- L$vec[4] - slider * 0.370
    L$vec[5] <- L$vec[5] - slider * 0.258
    L$vec[6] <- L$vec[6] - slider * 0.180
    L$vec[7] <- L$vec[7] - slider * 0.125
    L$vec[8] <- L$vec[8] - slider * 0.088
    L$vec[9] <- L$vec[9] - slider * 0.064
    L$vec[10] <- L$vec[10] - slider * 0.047
    
    # Creating The notifications for the feature metrics
    if (L$vec["Feature3"] > 145.61 & L$vec["Feature3"] < 151.69 ) {
      showNotification("Feature3 is * AMONG THE BEST *", duration = 10, closeButton = TRUE,
                       type ="warning")
    }
    if (L$vec["Feature3"] > 151.69 ) {
      showNotification("Feature3 is * BEST IN CLASS *", duration = 10, closeButton = TRUE,
                       type ="message")
    }
  }
  
} else if (input$feature == " Feature4") {
  
  #EXTRA CONDITION that prevents the other features from being negative while this feature is moved
  #The number 137 is found manually through trial error beyond which one of the features become negative
  if (L$vec["Feature4"] > 135.5) {
    output$errorMessage <- renderText({
      paste("You cannot increase further")
    })
  } else {
    
    L$vec[1] <- L$vec[1] - slider * 0.975
    L$vec[2] <- L$vec[2] - slider * 0.731
    L$vec[3] <- L$vec[3] - slider * 0.523
    L$vec[4] <- L$vec[4] + slider * 0.370
    L$vec[5] <- L$vec[5] - slider * 0.258
    L$vec[6] <- L$vec[6] - slider * 0.180
    L$vec[7] <- L$vec[7] - slider * 0.125
    L$vec[8] <- L$vec[8] - slider * 0.088
    L$vec[9] <- L$vec[9] - slider * 0.064
    L$vec[10] <- L$vec[10] - slider * 0.047
    
    # Creating The notifications for the feature metrics
    if (L$vec["Feature4"] > 130.205 & L$vec["Feature4"] < 134.945) {
      showNotification("Feature4 is * AMONG THE BEST *", duration = 10, closeButton = TRUE,
                       type ="warning")
    }
    if (L$vec["Feature4"] > 134.945 ) {
      showNotification("Feature4 is * BEST IN CLASS *", duration = 10, closeButton = TRUE,
                       type ="message")
    }
    
  } 
  
} else if (input$feature == " Feature5") {
  
  #EXTRA CONDITION that prevents the other features from being negative while this feature is moved
  #The number 126 is found manually through trial error beyond which one of the features become negative
  if (L$vec["Feature5"] > 124.8) {
    output$errorMessage <- renderText({
      paste("You cannot increase further")
    })
  } else {
    
    L$vec[1] <- L$vec[1] - slider * 0.975
    L$vec[2] <- L$vec[2] - slider * 0.731
    L$vec[3] <- L$vec[3] - slider * 0.523
    L$vec[4] <- L$vec[4] - slider * 0.370
    L$vec[5] <- L$vec[5] + slider * 0.258
    L$vec[6] <- L$vec[6] - slider * 0.180
    L$vec[7] <- L$vec[7] - slider * 0.125
    L$vec[8] <- L$vec[8] - slider * 0.088
    L$vec[9] <- L$vec[9] - slider * 0.064
    L$vec[10] <- L$vec[10] - slider * 0.047
    
    # Creating The notifications for the feature metrics
    if (L$vec["Feature5"] > 118.59 & L$vec["Feature5"] < 124) {
      showNotification("Feature5 is * AMONG THE BEST *", duration = 10, closeButton = TRUE,
                       type ="warning")
    }
    if (L$vec["Feature5"] > 124.11 ) {
      showNotification("Feature5 is * BEST IN CLASS *", duration = 10, closeButton = TRUE,
                       type ="message")
    }
  }
  
} else if (input$feature == " Feature6") {
  
  #EXTRA CONDITION that prevents the other features from being negative while this feature is moved
  #The number 118 is found manually through trial error beyond which one of the features become negative
  if (L$vec["Feature6"] > 116.8) {
    output$errorMessage <- renderText({
      paste("You cannot increase further")
    })
  } else {
    
    L$vec[1] <- L$vec[1] - slider * 0.975
    L$vec[2] <- L$vec[2] - slider * 0.731
    L$vec[3] <- L$vec[3] - slider * 0.523
    L$vec[4] <- L$vec[4] - slider * 0.370
    L$vec[5] <- L$vec[5] - slider * 0.258
    L$vec[6] <- L$vec[6] + slider * 0.180
    L$vec[7] <- L$vec[7] - slider * 0.125
    L$vec[8] <- L$vec[8] - slider * 0.088
    L$vec[9] <- L$vec[9] - slider * 0.064
    L$vec[10] <- L$vec[10] - slider * 0.047
    
    # Creating The notifications for the feature metrics
    if (L$vec["Feature6"] > 113.87 & L$vec["Feature6"] < 116 ) {
      showNotification("Feature6 is * AMONG THE BEST *", duration = 10, closeButton = TRUE,
                       type ="warning")
    }
    if (L$vec["Feature6"] > 116.23 ) {
      showNotification("Feature6 is * BEST IN CLASS *", duration = 10, closeButton = TRUE,
                       type ="message")
    }
  }
  
} else if (input$feature == " Feature7") {
  
  #EXTRA CONDITION that prevents the other features from being negative while this feature is moved
  #The number 112 is found manually through trial error beyond which one of the features become negative
  if (L$vec["Feature7"] > 111) {
    output$errorMessage <- renderText({
      paste("You cannot increase further")
    })
  } else {
    
    L$vec[1] <- L$vec[1] - slider * 0.975
    L$vec[2] <- L$vec[2] - slider * 0.731
    L$vec[3] <- L$vec[3] - slider * 0.523
    L$vec[4] <- L$vec[4] - slider * 0.370
    L$vec[5] <- L$vec[5] - slider * 0.258
    L$vec[6] <- L$vec[6] - slider * 0.180
    L$vec[7] <- L$vec[7] + slider * 0.125
    L$vec[8] <- L$vec[8] - slider * 0.088
    L$vec[9] <- L$vec[9] - slider * 0.064
    L$vec[10] <- L$vec[10] - slider * 0.047
    
    # Creating The notifications for the feature metrics
    if (L$vec["Feature7"] > 107 & L$vec["Feature7"] < 110 ) {
      showNotification("Feature7 is * AMONG THE BEST *", duration = 10, closeButton = TRUE,
                       type ="warning")
    }
    if (L$vec["Feature7"] > 110.32 ) {
      showNotification("Feature7 is * BEST IN CLASS *", duration = 10, closeButton = TRUE,
                       type ="message")
    }
  }
  
} else if (input$feature == " Feature8") {
  
  #EXTRA CONDITION that prevents the other features from being negative while this feature is moved
  #The number 109 is found manually through trial error beyond which one of the features become negative
  if (L$vec["Feature8"] > 108) {
    output$errorMessage <- renderText({
      paste("You cannot increase further")
    })
    
  } else {
    
    L$vec[1] <- L$vec[1] - slider * 0.975
    L$vec[2] <- L$vec[2] - slider * 0.731
    L$vec[3] <- L$vec[3] - slider * 0.523
    L$vec[4] <- L$vec[4] - slider * 0.370
    L$vec[5] <- L$vec[5] - slider * 0.258
    L$vec[6] <- L$vec[6] - slider * 0.180
    L$vec[7] <- L$vec[7] - slider * 0.125
    L$vec[8] <- L$vec[8] + slider * 0.088
    L$vec[9] <- L$vec[9] - slider * 0.064
    L$vec[10] <- L$vec[10] - slider * 0.047
    
    # Creating The notifications for the feature metrics
    if (L$vec["Feature8"] > 105.185 & L$vec["Feature8"] < 107 ) {
      showNotification("Feature8 is * AMONG THE BEST *", duration = 10, closeButton = TRUE,
                       type ="warning")
    }
    if (L$vec["Feature8 "] > 107.365 ) {
      showNotification("Feature8 is * BEST IN CLASS *", duration = 10, closeButton = TRUE,
                       type ="message")
    }
  }
} else if (input$feature == " Feature9 ") {
  
  #EXTRA CONDITION that prevents the other features from being negative while this feature is moved
  #The number 106 is found manually through trial error beyond which one of the features become negative
  if (L$vec["Feature9"] > 104.6) {
    output$errorMessage <- renderText({
      paste("You cannot increase further")
    })
  } else {
    
    L$vec[1] <- L$vec[1] - slider * 0.975
    L$vec[2] <- L$vec[2] - slider * 0.731
    L$vec[3] <- L$vec[3] - slider * 0.523
    L$vec[4] <- L$vec[4] - slider * 0.370
    L$vec[5] <- L$vec[5] - slider * 0.258
    L$vec[6] <- L$vec[6] - slider * 0.180
    L$vec[7] <- L$vec[7] - slider * 0.125
    L$vec[8] <- L$vec[8] - slider * 0.088
    L$vec[9] <- L$vec[9] + slider * 0.064
    L$vec[10] <- L$vec[10] - slider * 0.047
    
    # Creating The notifications for the feature metrics
    if (L$vec["Feature9"] > 102.29 & L$vec["Feature9"] < 104 ) {
      showNotification("Feature9 is * AMONG THE BEST *", duration = 10, closeButton = TRUE,
                       type ="warning")
    }
    if (L$vec["Feature9 "] > 104.41 ) {
      showNotification("Feature9 is * BEST IN CLASS *", duration = 10, closeButton = TRUE,
                       type ="message")
    }
  }
} else {
  
  #EXTRA CONDITION that prevents the other features from being negative while this feature is moved
  #The number 104.5 is found manually through trial error beyond which one of the features become negative
  if (L$vec["Feature10"] > 103) {
    output$errorMessage <- renderText({
      paste("You cannot increase further")
    })
  } else {
    
    L$vec[1] <- L$vec[1] - slider * 0.975
    L$vec[2] <- L$vec[2] - slider * 0.731
    L$vec[3] <- L$vec[3] - slider * 0.523
    L$vec[4] <- L$vec[4] - slider * 0.370
    L$vec[5] <- L$vec[5] - slider * 0.258
    L$vec[6] <- L$vec[6] - slider * 0.180
    L$vec[7] <- L$vec[7] - slider * 0.125
    L$vec[8] <- L$vec[8] - slider * 0.088
    L$vec[9] <- L$vec[9] - slider * 0.064
    L$vec[10] <- L$vec[10] + slider * 0.047
    
    # Creating The notifications for the feature metrics
    if (L$vec["Feature10"] > 101.5 & L$vec["Feature10"] < 102 ) {
      showNotification("Feature10 is * AMONG THE BEST *", duration = 10, closeButton = TRUE,
                       type ="warning")
    }
    if (L$vec["Feature10"] > 102.935 ) {
      showNotification("Feature10 is * BEST IN CLASS *", duration = 10, closeButton = TRUE,
                       type ="message")
    }
  }
}


cat("\n")
print(L$vec)

})

observeEvent(input$reset, {
output$errorMessage <- renderText({paste(“Let’s start again.”)})

output$textFE <- renderText({ if ( input$slider && input$feature == " Feature1") {
  
  paste(" Current Wt.", input$slider)
  
}
  })

cat("\n", "Reset", "\n")

L$vec <- c("Feature1" = 100, " Feature2" = 100, " Feature3" = 100,
           " Feature4" = 100, " Feature5" = 100, " Feature6" = 100, 
           " Feature7" = 100, " Feature8" = 100, " Feature9" = 100, " Feature10" = 100)

})

Creating the live output of slider

image2 sends pre-rendered images

output$textFE <- renderText({

if (input$slider && input$feature == " Feature1") {

      paste("Current Wt.", input$slider)

} else {

  if (input$slider == 10 ) {
  output$textFE <- renderText({
    paste("10")
  })

} else if (input$slider == 20 ) {
  output$textFE <- renderText ({
    paste("20")
  })

} else if (input$slider == 30 ) {
  output$textFE <- renderText ({
    paste("30")
  })

} else if (input$slider == 40 ) {
  output$textFE <- renderText ({
    paste("40")
  })

} else if (input$slider == 50 ) {
  output$textFE <- renderText ({
    paste("50")
  })

} else if (input$slider == 60 ) {
  output$textFE <- renderText ({
    paste("60")
  })

} else if (input$slider == 70 ) {
  output$textFE <- renderText ({
    paste("70")
  })

} else if (input$slider == 80 ) {
  output$textFE <- renderText ({
    paste("80")
  })

} else if (input$slider == 90 ) {
  output$textFE <- renderText ({
    paste("90")
  })

} else if (input$slider == 100 ) {
  output$textFE <- renderText ({
    paste("100")
  })
}

}

})

output$textVIS <- renderText({

if (input$feature == " Feature2") {

  paste("Current Wt.", input$slider)


}  else {

  if (input$slider == 10 ) {
    output$textVIS <- renderText({
      paste("10")
    })

  } else if (input$slider == 20 ) {
    output$textVIS <- renderText ({
      paste("20")
    })

  } else if (input$slider == 30 ) {
    output$textVIS <- renderText ({
      paste("30")
    })

  } else if (input$slider == 40 ) {
    output$textVIS <- renderText ({
      paste("40")
    })

  } else if (input$slider == 50 ) {
    output$textVIS <- renderText ({
      paste("50")
    })

  } else if (input$slider == 60 ) {
    output$textVIS <- renderText ({
      paste("60")
    })

  } 

}

})

output$textDPOS <- renderText({

if (input$slider && input$feature == " Feature3") {
  
  paste("Current Wt.", input$slider)
  
  
}  else {
  
  paste(" ")
  
}

})

output$textM <- renderText({

if (input$slider && input$feature == " Feature4") {
  
  paste("Current Wt.", input$slider)
  
  
}  else {
  
  paste(" ")
  
}

})

output$textRIC <- renderText({

if (input$slider && input$feature == " Feature5") {
  
  paste("Current Wt.", input$slider)
  
  
}  else {
  
  paste(" ")
  
}

})

output$textDRI <- renderText({

if (input$slider && input$feature == " Feature6") {
  
  paste("Current Wt.", input$slider)
  
  
}  else {
  
  paste(" ")
  
}

})

output$textRC <- renderText({

if (input$slider && input$feature == " Feature7") {
  
  paste("Current Wt.", input$slider)
  
  
}  else {
  
  paste(" ")
  
}

})

output$textCS <- renderText({

if (input$slider && input$feature == " Feature8") {
  
  paste("Current Wt.", input$slider)
  
  
}  else {
  
  paste(" ")
  
}

})

output$textQI <- renderText({

if (input$slider && input$feature == " Feature9") {
  
  paste("Current Wt.", input$slider)
  
  
}  else {
  
  paste(" ")
  
}

})

output$textREL <- renderText({

if (input$slider && input$feature == " Feature9") {
  
  paste("Current Wt.", input$slider)
  
  
}  else {
  
  paste(" ")
  
}

})

output$clickCount <- renderText({
input$go

})

output$bar_plot <- renderPlot({
#setting the margin size so everything is visible on x axis labels
par(mar = c(9.5, 4, 5, 2))

#Creating the bar plot
barplot(
  
  
  #reducing the width of bars in a bar plot
  space = 0.5,
  
  #Creating the bar plot with colors
  ylim=c(0,250),
  
  #Creating interactive bar plot
  t(as.matrix(L$vec)),
  main = 'Sample Feature Dependency Plot',
  ylab = "Operability",
  xlab = "",
  
  #Making the x axis labels vertical instead of horizontal
  las = 2,
  
  #increasing the size of x axis labels 
  cex.names = 1.2,
  
  # Creating a little tab box for colors at the top,
  args.legend = list(title = "Pop-up meaning", x = "topright", cex = .9),
  
  # Giving 3 different colors to feature metric increments - Best in class, competetive, above average 
  
  legend = c("Competitive", "Among the best", "Best in class"), 
  
  col = c("lightgrey", "gold", "skyblue4")
  
)

})

}
)