rshinygooglevis

How to display different tooltip texts for NA entries in a gvisGeoChart?


I have an app that displays countries in different colours according to their ranking. When you hover over the country, a box appears that displays their rank number, like so:

enter image description here

However, not all countries have enough data to qualify their ranking. For these countries, I want to show the name of the country and text that says "insufficient data" but that's it. You can see below that I haven't quite managed this because it still shows "Rank:" underneath. I'm sure that I've constructed the tooltip wrongly but I can't figure out how to fix it. How can I remove the "Rank:" for countries that don't have a rank? Or alternatively, how do I move "Insufficient data" to after "Rank:" for countries that don't have a rank?

enter image description here

Here is the code:

library(shiny)
library(googleVis)
library(dplyr)
library(DT)

# Load your data
combined_vul_data <- 
  structure(list(ISO3 = c("AF", "AL", "DZ", "AD", "AO", "AG", "AR", 
                          "AM", "AU", "AT", "AZ", "BS", "BH", "BD", "BB", "BY", "BE", "BZ", 
                          "BJ", "BT"), Name = c("Afghanistan", "Albania", "Algeria", "Andorra", 
                                                "Angola", "Antigua and Barbuda", "Argentina", "Armenia", "Australia", 
                                                "Austria", "Azerbaijan", "Bahamas", "Bahrain", "Bangladesh", 
                                                "Barbados", "Belarus", "Belgium", "Belize", "Benin", "Bhutan"
                          ), vul_capacity_Rank_2021 = c(0.709035449, 0.511126182, 0.523332101, 
                                                        NA, 0.740026186, 0.621133795, 0.446088596, 0.462491218, 0.296565054, 
                                                        0.26689445, 0.47917568, NA, 0.453936004, 0.649876424, 0.398904506, 
                                                        0.386808093, 0.27763708, 0.547525366, 0.763503499, 0.635633065
                          )), class = "data.frame", row.names = c(NA, -20L))


# Define UI for the map
ui <- fluidPage(
  titlePanel(div(span("Country Rankings"), style={'padding-top: 15px'})),
  tabsetPanel(
    tabPanel("Vulnerability Map",
             sidebarLayout(
               sidebarPanel(
                 selectInput("year", "Select Year", choices = 2021, selected = 2021),
                 selectInput("category", "Select Category", 
                             choices = list("Adaptive Capacity" = "vul_capacity"), selected = "vul_vulnerability")
               ),
               mainPanel(
                 htmlOutput("map")
               )
             )
    )
  )
)

# Define server logic for the map
server <- function(input, output) {
  output$map <- renderGvis({
    year <- input$year
    category <- input$category
    
    # Create the column name for the selected year and category
    rank_column <- paste(category, "_Rank_", year, sep = "")
    
    # Filter and prepare the data
    map_data <- combined_vul_data %>%
      select(ISO3, Name, Rank = !!sym(rank_column)) %>%
      mutate(Tooltip = ifelse(is.na(Rank), paste(Name, "- Insufficient data"), paste(Name)))
    
    # Update locationvar column
    map_data <- map_data %>%
      mutate(Location = ifelse(Name %in% c("Congo (Brazzaville)", "Congo (Kinshasa)"), ISO3, Name))
    
    # Determine the range of the Rank values
    min_rank <- min(map_data$Rank, na.rm = TRUE)
    max_rank <- max(map_data$Rank, na.rm = TRUE)
    
    # Create the map
    gvisGeoChart(map_data, locationvar = "Location", colorvar = "Rank",
                 hovervar = "Tooltip",  
                 options = list(colorAxis = paste0("{minValue:", min_rank, ", maxValue:", max_rank, ", colors:['#00FF00', '#FFFF00', '#FF0000']}"),
                                backgroundColor = '#81d4fa', datalessRegionColor = '#f5f5f5',
                                defaultColor = '#f5f5f5',
                                tooltip = "{isHtml: true}",
                                width = "100%",
                                height = "500px"))  
  })
  
}

shinyApp(ui = ui, server = server)

Solution

  • You need:

    Then it looks like this for a country with enough data:

    enter image description here

    And like this for a country without enough data (here manually set to Australia only for testing purposes):

    enter image description here

    library(shiny)
    library(googleVis)
    library(dplyr)
    library(DT)
    
    # Load your data
    combined_vul_data <- 
      structure(list(ISO3 = c("AF", "AL", "DZ", "AD", "AO", "AG", "AR", 
                              "AM", "AU", "AT", "AZ", "BS", "BH", "BD", "BB", "BY", "BE", "BZ", 
                              "BJ", "BT"), Name = c("Afghanistan", "Albania", "Algeria", "Andorra", 
                                                    "Angola", "Antigua and Barbuda", "Argentina", "Armenia", "Australia", 
                                                    "Austria", "Azerbaijan", "Bahamas", "Bahrain", "Bangladesh", 
                                                    "Barbados", "Belarus", "Belgium", "Belize", "Benin", "Bhutan"
                              ), vul_capacity_Rank_2021 = c(0.709035449, 0.511126182, 0.523332101, 
                                                            NA, 0.740026186, 0.621133795, 0.446088596, 0.462491218, 0.296565054, 
                                                            0.26689445, 0.47917568, NA, 0.453936004, 0.649876424, 0.398904506, 
                                                            0.386808093, 0.27763708, 0.547525366, 0.763503499, 0.635633065
                              )), class = "data.frame", row.names = c(NA, -20L))
    
    
    # Define UI for the map
    ui <- fluidPage(
      titlePanel(div(span("Country Rankings"), style={'padding-top: 15px'})),
      tabsetPanel(
        tabPanel("Vulnerability Map",
                 sidebarLayout(
                   sidebarPanel(
                     selectInput("year", "Select Year", choices = 2021, selected = 2021),
                     selectInput("category", "Select Category", 
                                 choices = list("Adaptive Capacity" = "vul_capacity"), selected = "vul_vulnerability")
                   ),
                   mainPanel(
                     htmlOutput("map")
                   )
                 )
        )
      )
    )
    
    # Define server logic for the map
    server <- function(input, output) {
      output$map <- renderGvis({
        year <- input$year
        category <- input$category
        
        # Create the column name for the selected year and category
        rank_column <- paste(category, "_Rank_", year, sep = "")
        
        # Filter and prepare the data
        map_data <- combined_vul_data %>%
          select(ISO3, Name, Rank = !!sym(rank_column)) %>%
          mutate(Rank.tooltip = ifelse(is.na(Rank), "", paste("Rank: <b>", round(Rank, 3), "</b>"))) |> 
          mutate(Tooltip.header = ifelse(is.na(Rank), paste(Name, "- Insufficient data"), Name))
        
        # Update locationvar column
        map_data <- map_data %>%
          mutate(Location = ifelse(Name %in% c("Congo (Brazzaville)", "Congo (Kinshasa)"), ISO3, Name))
        
        # Determine the range of the Rank values
        min_rank <- min(map_data$Rank, na.rm = TRUE)
        max_rank <- max(map_data$Rank, na.rm = TRUE)
        
        # Create the map
        gvisGeoChart(map_data, locationvar = "Location", colorvar = "Rank",
                     hovervar = "Tooltip.header",  
                     options = list(colorAxis = paste0("{minValue:", min_rank, ", maxValue:", max_rank, ", colors:['#00FF00', '#FFFF00', '#FF0000']}"),
                                    backgroundColor = '#81d4fa', datalessRegionColor = '#f5f5f5',
                                    defaultColor = '#f5f5f5',
                                    tooltip = "{isHtml: true}",
                                    width = "100%",
                                    height = "500px"))  
      })
      
    }
    
    shinyApp(ui = ui, server = server)