0
votes

This is my first question so I apologise if its not up to scratch, but I'm stuck on an issue and I really need help please.

I'm trying to create a shiny app, which will allow you to select a species from a drop down menu, thereby changing the colour of country polygons on a map, 1 colour for presence and another for absence. I've created a sf object with the shapefile data and merged it with a presence absence (1 +0 respectively) dataframe, the intention being that selection of this species will change input$SppSelect, selecting a different column in the merged sf object, and then this will cause my leaflet map to be redrawn with a new species occurrence.

To colour the map I intended to assign my species input variable to another variable: sppcol <- reactive({input$SppSel}), and then use Botpal <- reactive({colorFactor(viridis(2), BotCon$sppcol())}) to make a reactive palette. I'd then use fillColor = ~Botpal(Botcon$sspcol()) to change the colour of the polygons.

I'm not sure if I can produce a reprex but I'll attempt to illustrate how the app should work. Palms = csv file with every species occurrence next to the country its in:

( china : caryota mitis)

(china : caryota no)

(Bhutan : caryota mitis).

BotCon is the botanical countries shape file I'm working with. :

ui <- fluidPage(

  sidebarLayout(
    sidebarPanel(
      selectInput(inputId = "SppSel", 
                  label = "Species Selection",
                  choices = paste(Palms$SpecName)),
    ),
    mainPanel(
      leafletOutput("mymap", height=600)
    )))


server <- function(input, output) {

  PresAb <- create.matrix(Palms, tax.name = "SpecName", locality = "Area_code_L3")

  PresAb.df <- as.data.frame(t(PresAb))

  PresAb.dfnamed <- cbind(LEVEL3_COD = rownames(PresAb.df), PresAb.df)

  jointdataset <- merge(BotCon, PresAb.dfnamed, by = 'LEVEL3_COD', all.y=TRUE)

  sppcol <- reactive({input$SppSel})

  Botpal <- reactive({colorFactor(viridis(2), jointdataset$sppcol())})


  output$mymap <- renderLeaflet({
    leaflet() %>%
      addTiles() %>%
      addPolygons(data=jointdataset, 
                  stroke = TRUE,smoothFactor = 0.3, weight = 1, fillOpacity = 0.5,  
                  fillColor = ~Botpal(jointdataset$"caryota mitis")
  }) }

shinyApp(ui = ui, server = server)

My question is therefore; how can I use my species selection input, to select a different column of the merged dataset I've created, and colour my map polygons using the 1s and 0s present inside this column please?

(really sorry for the layout, I'm pretty much self taught for all this stuff too)

1
Please format code (not intended as inline) as a single chunk, using code fences: start with ```lang-r (on a line by itself), then uninterrupted code, then ``` (on a line by itself). (Ref: stackoverflow.com/editing-help)r2evans
Can you please format the code using code fences. this option is available when you edit this post.Abhi.G
Ah yepp sorry, thank you for pointing that out, I think it's already been edited but I'll make sure it's in the correct format next timeBen Raby

1 Answers

1
votes

Sure. We can do this when the color palette is created, i.e. this part of the code:
Botpal <- reactive({colorFactor(viridis(2), jointdataset$sppcol())})

I don't have your data or map file, so below is a generic minimal example:


library(leaflet)
library(maps)
library(shiny)


ui <- fluidPage(

    leafletOutput("map_1"),

    selectInput(inputId = "input_species", label = "Species Selection", choices = c("Species 1", "Species 2", "Species 3"))

)


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

    #Load a map of the US from the 'map' package (runs once when apps starts)
    shp_map = map("state", fill = TRUE, plot = FALSE)

    #Make up a dataframe with some data for three species for each state (runs once when apps starts)
    df_data <- expand.grid(state = unique(shp_map$names), species = c("Species 1", "Species 2", "Species 3"))
    df_data$value <- sample(1:1000, nrow(df_data))

    #Create map
    output$map_1 <- renderLeaflet({

        #Filter dataframe based on what species is selected
        df_map <- df_data[df_data$species == input$input_species ,]

        #Set color based on what species is selected
        if(input$input_species == "Species 1") {color_selected = "Blues"}
        if(input$input_species == "Species 2") {color_selected = "Reds"}
        if(input$input_species == "Species 3") {color_selected = "Greens"}

        #Create a palette function, using the selected color
        palette <- colorNumeric(palette = color_selected, domain = df_map$value)

        #Use the palette function created above to add the appropriate RGB value to our dataframe
        df_map$color <- palette(df_map$value)

        #Create map
        map_1 <- leaflet(data = shp_map) %>% 

            addPolygons(fillColor = df_map$color, fillOpacity = 1, weight = 1, color = "#000000", popup = paste(sep = "", "<b>", paste(shp_map$names), " ", "</b><br>", df_map$value)) 

        map_1

    })

}

shinyApp(ui, server)