带有 ggplot 地图的闪亮应用程序 - 多边形颜色与用户输入不匹配
Shiny app with ggplot map - polygons colors don't match user inputs
我正在尝试使用 Shiny 和 ggplot2 构建一个简单的地图应用程序。它的工作原理如下:
- 用户选择了一个国家
- 该应用加载一个形状文件并给出 adm1 国家/地区的输入字段列表
- 用户为每个区域输入一个数值(字段最初填充随机值)
- 来自输入字段的所有值都收集在一个向量中,合并到地图数据中并作为
fill
参数提供给 ggplot()
函数
问题是 ggplot 似乎没有正确解释每个区域的输入值。另外,当通过 UI 修改输入值时,地图上的颜色不会改变。我相信输入 fill
参数的 indicator
向量不正确 interpreted/passed.
感谢您的建议。
注意:在下面的代码中,shapefile 来源于 UCDavis 网站以实现可重现性。我一般都存放在本地。
ui.R
shinyUI(fluidPage(
sidebarLayout(
sidebarPanel(
selectInput("ctry", "Country:",
list("Burkina Faso"="BFA","Ethiopia"="ETH","Ghana"="GHA",
"Kenya"="KEN","Malawi"="MWI","Mali"="MLI"), selected="ETH"),
uiOutput("sliders")
),
mainPanel(
plotOutput('map', width = "100%")
)
)
)
)
server.R
x<-c("ggplot2","sp","maptools","rgdal","rgeos","scales","grid","gridExtra","plyr")
lapply(x, require, character.only=T)
rm(x)
shinyServer(function(input, output, session) {
gadm<-reactive ({
load(paste0("http://biogeo.ucdavis.edu/data/gadm2/R/",input$ctry,"_adm1.RData")) #load country shapefile
gadm@data$id <- rownames(gadm@data)
gadm.df <- fortify(gadm)
gadm.df <- join(gadm.df,gadm@data, by="id")
return(gadm.df)
})
output$sliders <- renderUI({
regions <- unique(gadm()$NAME_1) #get list of region names
numRegions <- length(regions) #get number of regions
lapply(1:numRegions, function(i) { #generate 1 input field per region
numericInput(paste0("reg",i), #with random values
label = regions[i], value = round(runif(1, 1.0, 7.5),2),
step=0.1) })
})
mapdata<- reactive({
regions <- unique(gadm()$NAME_1) #get list of region names
numRegions <- length(regions) #get number of regions
indicator <- input$reg1 #initate vector with first value of user inputs
for (i in 2:numRegions)(
indicator<-c(indicator,eval(paste0("input$reg",i))) #collect all user inputs values in a vector
)
indicator <- as.data.frame(t(rbind(indicator,regions)))#attribute region name to user input values
colnames(indicator)<-c("indicator","NAME_1")
merge(gadm(), indicator, by="NAME_1") #merge it with map data
})
themap <- function() {
ggplot() + geom_polygon(data=mapdata(),
aes(x=long, y=lat, group=group, fill=as.numeric(indicator) )) +
scale_fill_gradient("test",low="#99d8c9", high="#00441b") +
geom_path(data=mapdata(),
aes(x=long, y=lat, group=group), color='grey', size=0.15, alpha=0.6) +
coord_map()
}
output$map<-renderPlot({ themap() }, height = 700 )
})
问题是表达式eval(paste0("input$reg",i))
returns 你不是input$regN的内容,而是字符串"input$regN"。您可以使用双括号获取所需的输入元素:
x<-c("ggplot2","sp","maptools","rgdal","rgeos","scales","grid","gridExtra","plyr")
lapply(x, require, character.only=T)
rm(x)
shinyServer(function(input, output, session) {
gadm<-reactive ({
load(paste0(input$ctry,"_adm1.RData")) #load country shapefile
gadm@data$id <- rownames(gadm@data)
gadm.df <- fortify(gadm)
gadm.df <- join(gadm.df,gadm@data, by="id")
return(gadm.df)
})
output$sliders <- renderUI({
regions <- unique(gadm()$NAME_1) #get list of region names
numRegions <- length(regions) #get number of regions
lapply(1:numRegions, function(i) { #generate 1 input field per region
numericInput(paste0("reg",i), #with random values
label = regions[i], value = round(runif(1, 1.0, 7.5),2),
step=0.1) })
})
mapdata<- reactive({
regions <- unique(gadm()$NAME_1) #get list of region names
numRegions <- length(regions) #get number of regions
indicator <- sapply(seq_along(regions),function(i) input[[paste0('reg',i)]])
if (any(is.null(unlist(indicator)))) return()
indicator <- as.data.frame(cbind(indicator,regions))#attribute region name to user input values
colnames(indicator)<-c("indicator","NAME_1")
merge(gadm(), indicator, by="NAME_1") #merge it with map data
})
themap <- function() {
d <- mapdata()
if (is.null(d)) return()
ggplot() + geom_polygon(data=d,
aes(x=long, y=lat, group=group, fill=as.numeric(indicator) )) +
scale_fill_gradient("test",low="#99d8c9", high="#00441b") +
geom_path(data=d,
aes(x=long, y=lat, group=group), color='grey', size=0.15, alpha=0.6) +
coord_map()
}
output$map<-renderPlot({ themap() }, height = 700 )
})
请注意,mapdata() 可能会在 output$sliders 之前调用,因此 input$regN 在 mapdata() 评估时可能不存在。为了避免相关问题,我在上面的代码中插入了几个检查。
我正在尝试使用 Shiny 和 ggplot2 构建一个简单的地图应用程序。它的工作原理如下:
- 用户选择了一个国家
- 该应用加载一个形状文件并给出 adm1 国家/地区的输入字段列表
- 用户为每个区域输入一个数值(字段最初填充随机值)
- 来自输入字段的所有值都收集在一个向量中,合并到地图数据中并作为
fill
参数提供给ggplot()
函数
问题是 ggplot 似乎没有正确解释每个区域的输入值。另外,当通过 UI 修改输入值时,地图上的颜色不会改变。我相信输入 fill
参数的 indicator
向量不正确 interpreted/passed.
感谢您的建议。
注意:在下面的代码中,shapefile 来源于 UCDavis 网站以实现可重现性。我一般都存放在本地。
ui.R
shinyUI(fluidPage(
sidebarLayout(
sidebarPanel(
selectInput("ctry", "Country:",
list("Burkina Faso"="BFA","Ethiopia"="ETH","Ghana"="GHA",
"Kenya"="KEN","Malawi"="MWI","Mali"="MLI"), selected="ETH"),
uiOutput("sliders")
),
mainPanel(
plotOutput('map', width = "100%")
)
)
)
)
server.R
x<-c("ggplot2","sp","maptools","rgdal","rgeos","scales","grid","gridExtra","plyr")
lapply(x, require, character.only=T)
rm(x)
shinyServer(function(input, output, session) {
gadm<-reactive ({
load(paste0("http://biogeo.ucdavis.edu/data/gadm2/R/",input$ctry,"_adm1.RData")) #load country shapefile
gadm@data$id <- rownames(gadm@data)
gadm.df <- fortify(gadm)
gadm.df <- join(gadm.df,gadm@data, by="id")
return(gadm.df)
})
output$sliders <- renderUI({
regions <- unique(gadm()$NAME_1) #get list of region names
numRegions <- length(regions) #get number of regions
lapply(1:numRegions, function(i) { #generate 1 input field per region
numericInput(paste0("reg",i), #with random values
label = regions[i], value = round(runif(1, 1.0, 7.5),2),
step=0.1) })
})
mapdata<- reactive({
regions <- unique(gadm()$NAME_1) #get list of region names
numRegions <- length(regions) #get number of regions
indicator <- input$reg1 #initate vector with first value of user inputs
for (i in 2:numRegions)(
indicator<-c(indicator,eval(paste0("input$reg",i))) #collect all user inputs values in a vector
)
indicator <- as.data.frame(t(rbind(indicator,regions)))#attribute region name to user input values
colnames(indicator)<-c("indicator","NAME_1")
merge(gadm(), indicator, by="NAME_1") #merge it with map data
})
themap <- function() {
ggplot() + geom_polygon(data=mapdata(),
aes(x=long, y=lat, group=group, fill=as.numeric(indicator) )) +
scale_fill_gradient("test",low="#99d8c9", high="#00441b") +
geom_path(data=mapdata(),
aes(x=long, y=lat, group=group), color='grey', size=0.15, alpha=0.6) +
coord_map()
}
output$map<-renderPlot({ themap() }, height = 700 )
})
问题是表达式eval(paste0("input$reg",i))
returns 你不是input$regN的内容,而是字符串"input$regN"。您可以使用双括号获取所需的输入元素:
x<-c("ggplot2","sp","maptools","rgdal","rgeos","scales","grid","gridExtra","plyr")
lapply(x, require, character.only=T)
rm(x)
shinyServer(function(input, output, session) {
gadm<-reactive ({
load(paste0(input$ctry,"_adm1.RData")) #load country shapefile
gadm@data$id <- rownames(gadm@data)
gadm.df <- fortify(gadm)
gadm.df <- join(gadm.df,gadm@data, by="id")
return(gadm.df)
})
output$sliders <- renderUI({
regions <- unique(gadm()$NAME_1) #get list of region names
numRegions <- length(regions) #get number of regions
lapply(1:numRegions, function(i) { #generate 1 input field per region
numericInput(paste0("reg",i), #with random values
label = regions[i], value = round(runif(1, 1.0, 7.5),2),
step=0.1) })
})
mapdata<- reactive({
regions <- unique(gadm()$NAME_1) #get list of region names
numRegions <- length(regions) #get number of regions
indicator <- sapply(seq_along(regions),function(i) input[[paste0('reg',i)]])
if (any(is.null(unlist(indicator)))) return()
indicator <- as.data.frame(cbind(indicator,regions))#attribute region name to user input values
colnames(indicator)<-c("indicator","NAME_1")
merge(gadm(), indicator, by="NAME_1") #merge it with map data
})
themap <- function() {
d <- mapdata()
if (is.null(d)) return()
ggplot() + geom_polygon(data=d,
aes(x=long, y=lat, group=group, fill=as.numeric(indicator) )) +
scale_fill_gradient("test",low="#99d8c9", high="#00441b") +
geom_path(data=d,
aes(x=long, y=lat, group=group), color='grey', size=0.15, alpha=0.6) +
coord_map()
}
output$map<-renderPlot({ themap() }, height = 700 )
})
请注意,mapdata() 可能会在 output$sliders 之前调用,因此 input$regN 在 mapdata() 评估时可能不存在。为了避免相关问题,我在上面的代码中插入了几个检查。