rggplot2shinydashboardgeom-sf

Tell shiny I am talking about a data frame column name not a variable


So I am trying to create a shiny app in which I am plotting a map of India using sf data. I have uploaded a dataset which has multiple columns. So I ask the use to select the column. But when I gave that input to geom_sf(fill = input$select_topic) It firstly thinks the column name is a single char value, so I use geom_sf(fill = .data$input$select_topic) or geom_sf(fill = ,data[[input$select_topic]] ) which gives me error : Can't subset .data outside of a data mask context.

here is the code:

library(shiny)
library(tidyverse)
library(sf)


# joining the main datset and the sf dataset 

map_data <- read.csv("D:\\R Projects\\R experimental\\dashboard\\app-1\\app-1\\data\\edu_data.csv")
map_data <- as.data.frame(map_data)
map_data_2 <- left_join(India, map_data, by = "state_ut")


# Define UI ----
ui <- fluidPage(
  titlePanel("My Shiny App"),
  
  sidebarLayout(position = "right",
    sidebarPanel(
      
      selectInput("select_year", label = "Select Year", 
                  choices = list("2012-13" = 2012,
                                 "2013-14" = 2013, 
                                 "2014-15" = 2014,
                                 "2015-16" = 2015), selected = 2013),
      selectInput("select_topic", label = "Select Category", 
                  choices = list("Drinking Water Facility" = 'water_faci', 
                                 "Girl's Toilet Facility" = 'gtoi_faci',
                                 "Boy's Toilet Facility" = 'btoi_faci',
                                 "Electricity Connection" = 'elec_faci',
                                 "Computer availability" = 'comp_faci',
                                 "Overall Facilities" = 'all_faci',
                                 "Gross Enrollment" = 'gross_enroll',
                                 "Drop-out Rate" = 'drop_rate' 
                                 ), selected = "Drinking Water Facility")
      
    mainPanel(
      h1("Maps"),
      textOutput("selected_year"),
      textOutput("selected_category"),
      plotOutput("map")
      )
  )
  
)

# Define server logic ----
server <- function(input, output) {
  
  output$selected_year <- renderText({
    paste("You have selected the year:", input$select_year)
  })
  
  
  output$selected_category <- renderText({
    paste("You have selected category:", input$select_topic)
  })
  
  })
  output$map <- renderPlot({
    x <- map_data_2 %>% filter(., year == input$select_year)
    
    ggplot(x, aes(label = state_ut)) +
      geom_sf( fill = .data$input$select_topic ) +
      scale_fill_distiller(palette = "GnBu", 
                           direction= 1, 
                           na.value="grey") +
      theme_map() + 
      theme( plot.title = element_text(size=22), 
             legend.position = "left", 
             legend.justification ='left') 
  })  
  
}

# Run the app ----
shinyApp(ui = ui, server = server)

Here is the dataset whose column I need to select

state_ut year water_faci comp_faci btoi_faci gtoi_faci elec_faci all_faci gross_enroll drop_rate
All India 2013 95.4 24.08 86.56 91.23 56.78 70.81 79.89 6.88
Andaman & Nicobar Islands 2013 98.69 53.06 94.52 93.44 88.86 85.714 96.8 6.2
Andhra Pradesh 2013 90.35 29.57 56.88 81.31 90.34 69.69 78.95 8.14
Arunachal Pradesh 2013 79.79 24.28 48.73 76.9 36.35 53.21 98.58
Assam 2013 80.3 8.85 60.17 75.28 19.39 48.798 77.68 13.04
Bihar 2013 92.53 5.47 73.42 75.41 9.96 51.358 67.24
Chandigarh 2013 100 95.83 100 100 100 99.166 94.18
Chhattisgarh 2013 95.47 9.8 82.85 94.1 57.28 67.9 89.98
output$map <- renderPlot({
    x <- map_data_2 %>% filter(., year == input$select_year)

    ggplot(x, aes(label = state_ut)) +
      geom_sf( fill = input$select_topic ) +
      scale_fill_distiller(palette = "GnBu", 
                           direction= 1, 
                           na.value="grey") +
      theme_map() + 
      theme( plot.title = element_text(size=22), 
             legend.position = "left", 
             legend.justification ='left') 
  })

will result in a map which has taken the fill values as a column present in the dataset.


Solution

  • Change your fill= in two ways:

    output$map <- renderPlot({
        x <- map_data_2 %>% filter(., year == input$select_year)
    
        ggplot(x, aes(label = state_ut)) +
          geom_sf(aes(fill = .data[[ input$select_topic ]])) +
          scale_fill_distiller(palette = "GnBu", 
                               direction= 1, 
                               na.value="grey") +
          theme_map() + 
          theme( plot.title = element_text(size=22), 
                 legend.position = "left", 
                 legend.justification ='left') 
      })
    

    See https://ggplot2.tidyverse.org/articles/ggplot2-in-packages.html#using-aes-and-vars-in-a-package-function-1 for how to reference column names indirectly.