2

First, I have a perfect solution here how to create a Shiny leaflet map and filters based on rows.

Now I want to show a very similar map, where filters are applied to columns. Stumbled a little bit.

I want to create a map of US adult smoking by year, highlighting % with different colors.

Data in .csv format is here

Shapefiles are here

Currently, my map looks like this

Currently, my map looks like this

This is my code:

# Set directory
setwd("C:/DC/R/Shiny/US Adult Smoking by State")

# Upload packages
library(ggthemes)
library(rgdal)
library(sp)
library(leaflet)
library(shinythemes)

# Read dataset
smoking <- read.csv("US adult smoking by state1.csv", header = TRUE)

# Leaflet map
states <- readOGR(dsn = "C:/DC/R/Cool datasets/US smoking", layer = 
"cb_2016_us_state_500k", 
              encoding = "UTF-8", verbose = FALSE)

# Merge data
# require(sp)! For spatial dataframe!
smoking.df <- merge(states, smoking, by.x = "NAME", by.y = "state")
class(smoking.df)

# Create palette
pal <- colorBin("Reds", c(0, 30), na.color = "#808080",
            alpha = FALSE, reverse = FALSE)


# UI
ui <- shinyUI(fluidPage(theme = shinytheme("united"),
                    titlePanel(HTML("<h1><center><font size=14> US Adult 
Smoking by State in 2015-2017</font></center></h1>")), 
                    sidebarLayout(
                      sidebarPanel(
                        selectInput("stateInput", label = h3("State"),
                                    choices = c("Choose state",
                                                "Alabama",
                                                "Alaska",
                                                "Arizona",
                                                "Arkansas",
                                                "California",
                                                "Colorado",
                                                "Connecticut",
                                                "Delaware",
                                                "Florida",
                                                "Georgia",
                                                "Hawaii",
                                                "Idaho",
                                                "Illinois",
                                                "Indiana",
                                                "Iowa",
                                                "Kansas",
                                                "Kentucky",
                                                "Louisiana",
                                                "Maine",
                                                "Maryland",
                                                "Massachusetts",
                                                "Michigan",
                                                "Minnesota",
                                                "Mississippi",
                                                "Missouri",
                                                "Montana",
                                                "Nebraska",
                                                "Nevada",
                                                "New Hampshire",
                                                "New Jersey",
                                                "New Mexico",
                                                "New York",
                                                "North Carolina",
                                                "North Dakota",
                                                "Ohio",
                                                "Oklahoma",
                                                "Oregon",
                                                "Pennsylvania",
                                                "Rhode Island",
                                                "South Carolina",
                                                "South Dakota",
                                                "Tennessee",
                                                "Texas",
                                                "Utah",
                                                "Vermont",
                                                "Virginia",
                                                "Washington",
                                                "West Virginia",
                                                "Wisconsin",
                                                "Wyoming"
                                                ),
                                    selected = "Choose state"),
                        selectInput("stateInput", label = h3("State"),
                                    choices = c("Choose year",
                                                "2015",
                                                "2016",
                                                "2017"),
                                    selected = "Choose year")),
                      mainPanel(leafletOutput(outputId = 'map', height = 
800) 
                          ))
                    ))



# SERVER
server <- shinyServer(function(input, output) {
output$map <- renderLeaflet({
leaflet(smoking.df) %>% 
  addProviderTiles(providers$Stamen.TonerLite) %>% 
  setView(lng = -98.583, lat = 39.833, zoom = 4) #%>% 

})
# observers

# selected state
selectedState <- reactive({
smoking.df[smoking.df$NAME == input$stateInput, ] 
})

observe({
state_popup <- paste0("<strong>State: </strong>", 
                      selectedState()$NAME, 
                      "<br><strong>% of smoking adults in 2015: </strong>",
                      selectedState()$adult_smoking_2015,
                      "<br><strong>% of smoking adults in 2016: </strong>",
                      selectedState()$adult_smoking_2016,
                      "<br><strong>% of smoking adults in 2017: </strong>",
                      selectedState()$adult_smoking_2017)

leafletProxy("map", data = selectedState()) %>%
  clearShapes() %>%
  addPolygons(fillColor = "orange",
              popup = state_popup,
              color = "#BDBDC3",
              fillOpacity = 0.8,
              weight = 1)
})

# selected year
selectedYear <- reactive({
smoking.df[smoking.df$adult_smoking_2015 == input$yearInput &
           smoking.df$adult_smoking_2016 == input$yearInput &
           smoking.df$adult_smoking_2017 == input$yearInput,] 
})

observe({
state_popup1 <- paste0("<strong>State: </strong>", 
                      selectedState()$NAME)

leafletProxy("map", data = selectedYear()) %>%
  clearShapes() %>%
  addPolygons(fillColor = ~pal(selectedYear()$yearInput),
              popup = state_popup1,
              color = "#BDBDC3",
              fillOpacity = 0.8,
              weight = 1)
})


})


# Run app! 
shinyApp(ui = ui, server = server)

So, my assumption that I am screwing up with inputYear, and also with the color palette in leaflet map. Years are in columns and it is a little bit difficult for me now to understand where is my mistake.

Super grateful for all hints. Hopefully, my question will also help other people.

My desirable outcome, which I created just in leaflet below. I want to change year in a filter and receive the change on a map. enter image description here

Anakin Skywalker
  • 2,400
  • 5
  • 35
  • 63
  • 1
    Funny, you created the desirable output already, so why to ask for a solution when you have it in hand? Or I misunderstand what you stated? Also, in this version you do not input the state as a parameter, rather, the only parameter is the year, correct? – Patrik_P Sep 24 '17 at 17:40
  • @Patrik_P, my output was created in the leaflet, yes, but it is a single map. I want to put it in Shiny. Three maps for each year. Server filter does not work so far. – Anakin Skywalker Sep 24 '17 at 18:30

1 Answers1

1

Preliminary solution (not mine, from other smart people). Plus the shapefile was substituted with geojson one.

# Upload packages
library(rgdal)
library(sp)
library(leaflet)
library(geojsonio)
library(shinythemes)
library(shiny)

# Read dataset
smoking <- read.csv("US adult smoking by state1.csv", header = TRUE)

# Leaflet map
# states <- readOGR(dsn = ".", layer = 
#                    "cb_2016_us_state_500k", 
#                   encoding = "UTF-8", verbose = FALSE)

states <- geojson_read("gz_2010_us_040_00_500k.json",what = "sp")

# Merge data
# require(sp)! For spatial dataframe!
smoking.df <- merge(states, smoking, by.x = "NAME", by.y = "state")


# UI
ui <- shinyUI(fluidPage(theme = shinytheme("united"),
                    titlePanel(HTML("<h1><center><font size=14> US Adult 
                                    Smoking by State in 2015-2017</font>
</center></h1>")), 
                    sidebarLayout(
                      sidebarPanel(
                        selectizeInput(
                          "stateInput", 'State', choices = "", multiple = 
FALSE,
                          options = list(
                            placeholder = 'Please select a state from 
below')
                        )
                        ,
                        selectInput("yearInput", label = h3("Year"),
                                    choices = c("Choose year", "2015", # 
 Choose year was added!
                                                "2016",
                                                "2017"))),
                      mainPanel(leafletOutput(outputId = 'map', height = 
                                                800) 
                      ))
                    ))


# SERVER
server <- shinyServer(function(input, output, session) {

updateSelectizeInput(session, "stateInput", choices = smoking.df$NAME,
                   server = TRUE)
# selected state
selectedState <- reactive({
smoking.df[smoking.df$NAME == input$stateInput, ] 
})
# selected year
selectedYear <- reactive({switch(input$yearInput, 
                               "2015"=smoking.df$adult_smoking_2015, 
                               "2016"=smoking.df$adult_smoking_2016, 
                               "2017"=smoking.df$adult_smoking_2017)
})
pal2 <- colorNumeric(palette = "Reds", domain=NULL)

output$map <- renderLeaflet({
leaflet(smoking.df) %>% 
  addProviderTiles(providers$Stamen.TonerLite) %>% 
  setView(lng = -98.583, lat = 39.833, zoom = 4) %>%
  addPolygons(data = smoking.df ,fillColor = ~pal2(selectedYear()),
              popup = paste0("<strong>State: </strong>", 
                             smoking.df$NAME),
              color = "#BDBDC3",
              fillOpacity = 0.8,
              weight = 1)

  })

  observeEvent(input$stateInput, {
  state_popup <- paste0("<strong>State: </strong>", 
                      selectedState()$NAME, 
                      "<br><strong>% of smoking adults in 2015: </strong>",
                      selectedState()$adult_smoking_2015,
                      "<br><strong>% of smoking adults in 2016: </strong>",
                      selectedState()$adult_smoking_2016,
                      "<br><strong>% of smoking adults in 2017: </strong>",
                      selectedState()$adult_smoking_2017)

    leafletProxy("map", data = selectedState()) %>%
  clearGroup(c("st.ate")) %>%
  addPolygons(group ="st.ate",fillColor = "orange",
              popup = state_popup,
              color = "#BDBDC3",
              fillOpacity = 0.8,
              weight = 5)
})

})

# Run app! 
shinyApp(ui = ui, server = server)

Current outputs: Just a map by year

A map by year with selected state

Current problems:

  1. Map is still slow with geojson, 2 seconds for changing years, it is redrawing.

  2. Gray color is on a map without any picks. Any ideas? As for now

Will keep you posted, will try to add one more filter.

Anakin Skywalker
  • 2,400
  • 5
  • 35
  • 63
  • 1
    On point 1.: You geojson solution is memory expensive, it's reading more than 2 MB of that file. Why not simple 400kb of shapefile downloadable from arcgis and reading that https://www.arcgis.com/home/item.html?id=f7f805eb65eb4ab787a0a3e1116ca7e5; `states <- readOGR("states.shp")`? 2.: It´s grey because you chose nothing to be selected on the launching of the app. If you wanna have a representation you need to feed it data, for instance from the year 2015 – Patrik_P Sep 27 '17 at 22:05
  • @Patrik_P, thanks for your comment! Well, I thought geojson is vice versa less consuming. I did with shapefile before and it is much slower. 5 sec for changing a filter, looks like map "thinks" a lot. Because it is probably redrawn every time. Speaking about grey, I never had anything gray in a simple leaflet. Here is it different. And I have another apps, which works perfectly without gray at all. For example, check this https://stackoverflow.com/questions/46186014/changing-leaflet-map-according-to-input-without-redrawing-multiple-polygons – Anakin Skywalker Sep 28 '17 at 19:01