我正在使用Shiny,并遇到了关于Leaflet的问题。
我的目标: 我的项目的最终目标是选择特定的法国县。当选择这些县时,我会实时创建形状文件(用于在Leaflet上绘制地图所必需的)和包含所有公共数据的数据库(例如人口数量等),这些数据仅对应于这些特定的县。
我的问题: 我知道"合并"操作在Shiny App内完成得很好。但是,我的输出地图无法工作。
详情:
事实上,我在另一个.R脚本上运行了我的“合并和绘图”代码,并且它完美地工作(只定义了我想要绘制的县)。 在我的ShinyApp中,这个选择由input$choix_depa
变量决定。
现在,稍微看一下代码。我有三个同时响应的脚本:global.R、ui.R和server.R(这就是Shiny的工作方式)。 对于global.R(我仅展示“有趣”的部分),我加载包含所有县的数据文件(不是形状文件!只是数据)。
setwd('path')
data_BP = read_delim(
"database-allFrance.csv",
",",
na = "empty",
quote = "\"",
locale = locale(encoding = 'windows-1252')
)
在 ui.R(用户界面)中,我有我的县“选择”:
shinydashboard::tabItem(tabName= "Departements", class = 'active',
shiny::fluidPage(
shiny::absolutePanel(
draggable = FALSE,
fixed = TRUE,
top = 60, left = "auto", right = 20, bottom = "auto",
width = 330, height = "auto",
wellPanel(
shiny::h4("Départements"),
selectizeInput(inputId = "choix_depa", label = "",multiple=TRUE,
choices = seq(1,95))
)
), textOutput("answ")
),
selectizeInput
是一个按钮,允许用户在 seq(1,95)
中选择一个或多个县。
而且在 server.R 文件中(最重要的文件)我有以下内容:
ObserveEvent(input$choix_depa, {
output$answ<- renderText({
paste("You choose", input$choix_depa)
})
choice=input$choix_depa
print(choice)
for (i in input$choix_depa){
setwd(sprintf("path/county%s",i))
assign(paste("contouriris",i,sep=""), readOGR(
dsn = "contours_IRIS_BP.shp",
layer = "contours_IRIS_BP",
verbose = FALSE,
encoding = 'UTF-8'
))
print("modification en cours...")
assign(paste("data_BP",i,sep=""),subset(data_BP,as.numeric(as.character(data_BP$IRIS))>=as.numeric(i)*10000000&as.numeric(as.character(data_BP$IRIS))<(as.numeric(i)+1)*10000000))
}
if (length(input$choix_depa)>=1){
contours_IRIS <- get(paste("contouriris",input$choix_depa[1],sep=""))
data_BPC <- get(paste("data_BP",input$choix_depa[1],sep=""))
}
if (length(input$choix_depa)>1){
for (i in input$choix_depa[-1]){
contours_IRIS <- rbind(contours_IRIS,get(paste("contouriris",i,sep="")))
data_BPC <- rbind(data_BPC,get(paste("data_BP",i,sep="")))
}
}
map_WGS84 = spTransform(
merge(contours_IRIS, data_BPC, by.x = 'CODE_IRIS', by.y = 'IRIS'),
CRS("+init=epsg:4326")
)
# Correction of names :
names(map_WGS84)[names(map_WGS84) == "TYP_IRIS.x"] <- "TYP_IRIS"
})
您不必理解所有这些代码。在
input$choix_depa
变量中,您可以选择县。这种类型的变量类似于["4',"87"],如果用户在应用程序内选择了县4和87(例如)。我在计算机上有95个文件夹(每个县一个文件夹)。我使用setwd来进入正确的路径,并在contouririsK
中加载“shape file”,其中K是县的编号。在前面的例子中,我们将有contouriris4
和countouriris87
。这些形状文件合并在contours_IRIS
中。我对数据文件执行相同的操作,取出与这些县相关联的数据,并将所有文件合并在data_BPC
中。(如果我采用之前的例子,我们将在data_BPC
中合并data_BPC4
和data_BPC87
)。此后,我使用两个变量(
contours_IRIS
和data_BPC
)创建map_WGS84
变量(我将需要此变量进行LeafletOutput)。好的,所以,在选择要在Leaflet地图上绘制的县之后,我必须选择我感兴趣的变量。这是另一个菜单,我不在此处编写所有代码(不必要)。observeEvent(input$choix_var_pop, {XXXXXXXXX})
用户想要在地图上绘制的变量选择在
input$choix_var_pop
中。
之后,我创建了我在LeafletMap中需要的特定变量:label_reac_pop = reactive({as.character(input$choix_var_pop)})
var_reac_pop = reactive({dico$Variable[dico$Label == label_reac_pop()]})
col_reac_pop = reactive({as.character(dico$Couleur[dico$Label == label_reac_pop()])})
type_reac_pop = reactive({as.character(dico$Type[dico$Label == label_reac_pop()])})
unite_reac_pop = reactive({ifelse(as.character(type_reac_pop()) == "Pct", " %", "")})
最后,我绘制了LeafletMap:(为了清晰起见,我已经大大简化了以下代码)
output$Carte_Pop <- renderLeaflet({
label = label_reac_pop()
var = var_reac_pop()
col = col_reac_pop()
type = type_reac_pop()
unite = unite_reac_pop()
values_var = map_WGS84@data[,var]
leaflet(map_WGS84) %>%
addProviderTiles("CartoDB.PositronNoLabels") %>%
addProviderTiles("CartoDB.PositronOnlyLabels") %>%
setView(lng = 2.468738900000062, lat = 49.19316, zoom = 7) %>%
clearShapes() %>%
clearPopups() %>%
})
当然,我在ui.R文件中称这个输出为$Carte_Pop,以便绘制它。那么这一系列操作的结果是什么呢?就像我之前提到的那样,当该脚本"单独"运行时,而且没有choix_depa(我手动输入要合并的县,并且它们很好地合并了,地图也很好地绘制了)。但是,当我在ShinyApp上使用我的三个脚本(global.R、ui.R和server.R)时,"地图"的新值未被"保存"。例如:如果在我的alone-script(独立脚本)上选择要合并和绘制4号和87个县,那么(合并部分和绘图部分都可以正常工作)!但是,当我启动我的ShinyApp时,当我选择我想要的县(例如13和91),即使和与对应于13和91的数据成功合并,所以我认为在观察事件后创建的与13和91相符,当我要求绘制特定变量(在之后),绘制的地图不是之前创建的地图,而是旧的地图,其中包含4和87(在"alone-script"中创建的地图)......在启动ShinyApp之前!但我100%确定,在中创建的MAP是正确的。但是,ShinyApp没有"保存"这个MAP的值(而是使用旧地图的值)。那么我的问题是:我该怎么做才能绘制好的新地图(在APP内部创建)?而不是坏的老地图(在APP之前创建)?这个问题有点复杂,如果你有任何问题,请随时问!谢谢!:)