闪亮:如何在同一张传单地图上绘制多个参数?

Shiny: how to plot several parameters on the same leaflet map?

我是 shiny 的新手。我想制作一个闪亮的应用程序来显示不同参数的空间分布。我使用了 sp 包中的 meuse 数据集。

这是我使用的代码

library(sp)
library(rgdal)
library(ggmap)
library(leaflet)
library(dplyr)
library(shiny)

ui <- fluidPage(
  mainPanel(
  titlePanel("Copper (ppm)"),
  leafletOutput("copper"),
  titlePanel("Lead (ppm)"),
  leafletOutput("lead"),
  titlePanel("Zinc (ppm)"),
  leafletOutput("zinc")
   )
  )
server <- function(input,output){
  output$copper <- renderLeaflet({

data(meuse)
coordinates(meuse) <- 1:2
proj4string(meuse) <- CRS("+init=epsg:28992")                 
meuse <- spTransform(meuse, CRS("+proj=longlat +datum=WGS84"))
meuse_df <- as.data.frame(meuse)

leaflet(meuse_df) %>% 
  addProviderTiles("OpenStreetMap", group = "OpenStreetMap") %>% 
  addProviderTiles("Esri.WorldImagery", group = "Esri.WorldImagery") %>%
  addCircleMarkers(~x, 
                   ~y, 
                   radius = ~copper/10,
                   stroke = FALSE, 
                   fillOpacity = 0.4, 
                   group = "meuse_df",
                   popup = ~as.character(copper)) %>%
addLayersControl(position = "bottomleft",
                 baseGroups = c("OpenStreetMap",
                            "Esri.WorldImagery"),
overlayGroups = "meuse_df")
})
  output$lead <- renderLeaflet({

  leaflet(meuse_df) %>% 
  addProviderTiles("OpenStreetMap", group = "OpenStreetMap") %>% 
  addProviderTiles("Esri.WorldImagery", group = "Esri.WorldImagery") %>%
  addCircleMarkers(~x, 
                   ~y, 
                   radius = ~lead/50,
                   stroke = FALSE, 
                   fillOpacity = 0.4, 
                   group = "meuse_df",
                   popup = ~as.character(lead)) %>%
  addLayersControl(position = "bottomleft",
                   baseGroups = c("OpenStreetMap",
                                  "Esri.WorldImagery"),
                   overlayGroups = "meuse_df")
})

output$zinc <- renderLeaflet({

leaflet(meuse_df) %>% 
  addProviderTiles("OpenStreetMap", group = "OpenStreetMap") %>% 
  addProviderTiles("Esri.WorldImagery", group = "Esri.WorldImagery") %>%
  addCircleMarkers(~x, 
                   ~y, 
                   radius = ~zinc/100,
                   stroke = FALSE, 
                   fillOpacity = 0.4, 
                   group = "meuse_df",
                   popup = ~as.character(zinc)) %>%
  addLayersControl(position = "bottomleft",
                   baseGroups = c("OpenStreetMap",
                                  "Esri.WorldImagery"),
                   overlayGroups = "meuse_df")
})
}
shinyApp(ui = ui, server = server) 

这是我得到的结果

我想知道是否有办法在一张地图上绘制所有参数(铜、铅和锌)。如有任何建议,我们将不胜感激。

更新

感谢@Symbolix 的回答和使用 checkBoxGroupInput 的建议。相反,我使用了 addCircleMarkers 三次,这样我就可以在一张地图上绘制所有金属,并且可以打开和关闭它们

ui <- fluidPage(
mainPanel(
titlePanel("All metals (ppm)"),
leafletOutput("metals")
)
)
server <- function(input,output){
output$metals <- renderLeaflet({

data(meuse)
coordinates(meuse) <- 1:2
proj4string(meuse) <- CRS("+init=epsg:28992")                 
meuse <- spTransform(meuse, CRS("+proj=longlat +datum=WGS84"))
meuse_df <- as.data.frame(meuse)

leaflet(meuse_df) %>% 
  addProviderTiles("OpenStreetMap", group = "OpenStreetMap") %>% 
  addProviderTiles("Esri.WorldImagery", group = "Esri.WorldImagery") %>%
  addCircleMarkers(~x, 
                   ~y, 
                   radius = ~copper/10,
                   color ="red",
                   stroke = FALSE, 
                   fillOpacity = 0.4, 
                   group = "copper",
                   popup = ~as.character(copper)) %>%
  addCircleMarkers(~x, 
                   ~y, 
                   radius = ~lead/50,
                   color ="gren",
                   stroke = FALSE, 
                   fillOpacity = 0.4, 
                   group = "lead",
                   popup = ~as.character(lead)) %>%
  addCircleMarkers(~x, 
                   ~y, 
                   radius = ~zinc/100,
                   color ="blue",
                   stroke = FALSE, 
                   fillOpacity = 0.4, 
                   group = "zinc",
                   popup = ~as.character(zinc)) %>%
  addLayersControl(position = "bottomleft",
                   baseGroups = c("OpenStreetMap",
                                  "Esri.WorldImagery"),
                   overlayGroups = c("copper",
                                     "lead",
                                     "zinc"))
})
}
shinyApp(ui = ui, server = server) 

熔化您的数据,使您的金属在一列中,您就可以开始了。

这里我用library(reshape2)做熔化

library(sp)
library(rgdal)
library(ggmap)
library(leaflet)
library(dplyr)
library(shiny)
library(reshape2)

ui <- fluidPage(
    mainPanel(
        titlePanel("Metals"),
        leafletOutput("all_metals")
    )
)
server <- function(input,output){

    output$all_metals <- renderLeaflet({

        data(meuse)
        coordinates(meuse) <- 1:2
        proj4string(meuse) <- CRS("+init=epsg:28992")                 
        meuse <- spTransform(meuse, CRS("+proj=longlat +datum=WGS84"))
        meuse_df <- as.data.frame(meuse)

        ## melt df so 'metals' are in one column
        ## using 'reshape2' library
        meuse_melt <- melt(meuse_df, measure.vars = c("copper","lead","zinc"), variable.name = "metal")

        ## specify factor levels for colours
        meuse_melt$metal <- factor(sample.int(5L, nrow(meuse_melt), TRUE))
        factpal <- colorFactor(topo.colors(5), meuse_melt$metal)

        ## now you just need one output
        leaflet(meuse_melt) %>% 
            addProviderTiles("OpenStreetMap", group = "OpenStreetMap") %>% 
            addProviderTiles("Esri.WorldImagery", group = "Esri.WorldImagery") %>%
            addCircleMarkers(~x, 
                             ~y, 
                             radius = ~value/100,
                             stroke = FALSE, 
                             fillOpacity = 0.4, 
                             group = "meuse_melt",
                             popup = ~metal,
                             color= ~factpal(metal)) %>%
            addLayersControl(position = "bottomleft",
                             baseGroups = c("OpenStreetMap", "Esri.WorldImagery"), overlayGroups = "meuse_melt") 
    })

}
shinyApp(ui = ui, server = server) 

为了节省代码行,您可以使用 mapview,它提供开箱即用的多层地图。如果您只需要某些属性,您可以简单地将它们的名称(或列号)提供给 'zcol' 参数。或者,您可以使用 'burst = TRUE' 显示属性 table.

中存在的所有 layers/columns
library(mapview)
library(sp)

data(meuse)
coordinates(meuse) <- ~x+y
proj4string(meuse) <- CRS("+init=epsg:28992")                 
mapview(meuse, zcol = c("copper", "lead", "zinc"))  

## all layers
mapview(meuse, burst = TRUE)

mapview 可以与 renderLeaflet 一起使用。