[朋友,您能帮我在发光的物体上插入坐标之间的距离吗?基本上,我的闪亮对象具有与所需聚类数量相对应的sliderInput,后跟一个选项,他希望在地图上看到哪个聚类,以及第二个选项,他想要看到所选聚类的哪个行业。到目前为止,它工作正常。请注意,在地图上始终有一个定位点和一个行业,因为为了生成地图,我将数据库df与数据库df1结合在一起。但是,我想添加另一个功能,该功能是计算此定位点与行业之间的距离。我插入了一张图片,以更好地说明我的想法。我相信距离计算公式也是我在下面插入的公式,我只需要帮助闪亮即可在我创建的textInput(Filter3)中显示距离。如果不是textInput,也可以是另一种方式。因此,无论何时选择集群和行业,我都打算展示它们之间的距离。可执行代码如下。
library(shiny)
library(ggplot2)
library(rdist)
library(geosphere)
library(shinythemes)
library(leaflet)
function.cl<-function(df,k,Filter1,Filter2,Filter3){
df<-structure(list(Industries = c(1,2,3,4,5,6),
Latitude = c(-23.8, -23.8, -23.9, -23.7, -23.7,-23.7),
Longitude = c(-49.5, -49.6, -49.7, -49.8, -49.6,-49.9),
Waste = c(526, 350, 526, 469, 534, 346)), class = "data.frame", row.names = c(NA, -6L))
#clusters
coordinates<-df[c("Latitude","Longitude")]
d<-as.dist(distm(coordinates[,2:1]))
fit.average<-hclust(d,method="average")
clusters<-cutree(fit.average, k)
nclusters<-matrix(table(clusters))
df$cluster <- clusters
#Center of mass
center_mass<-matrix(nrow=k,ncol=2)
for(i in 1:k){
center_mass[i,]<-c(weighted.mean(subset(df,cluster==i)$Latitude,subset(df,cluster==i)$Waste),
weighted.mean(subset(df,cluster==i)$Longitude,subset(df,cluster==i)$Waste))}
coordinates$cluster<-clusters
center_mass<-cbind(center_mass,matrix(c(1:k),ncol=1))
#Coverage
coverage<-matrix(nrow=k,ncol=1)
for(i in 1:k){
aux_dist<-distm(rbind(subset(coordinates,cluster==i),center_mass[i,])[,2:1])
coverage[i,]<-max(aux_dist[nclusters[i,1]+1,])}
coverage<-cbind(coverage,matrix(c(1:k),ncol=1))
colnames(coverage)<-c("Coverage_meters","cluster")
#Sum of Waste from clusters
sum_waste<-matrix(nrow=k,ncol=1)
for(i in 1:k){
sum_waste[i,]<-sum(subset(df,cluster==i)["Waste"])
}
sum_waste<-cbind(sum_waste,matrix(c(1:k),ncol=1))
colnames(sum_waste)<-c("Potential_Waste_m3","cluster")
#Tables to join information above and generate df1
data_table <- Reduce(merge, list(df, coverage,sum_waste))
data_table <- data_table[order(data_table$cluster, as.numeric(data_table$Industries)),]
data_table_1 <- aggregate(. ~ cluster + Coverage_meters + Potential_Waste_m3, data_table[,c(1,5,6,7)], toString)
df1<-as.data.frame(center_mass)
colnames(df1) <-c("Latitude", "Longitude", "cluster")
#specific cluster and specific propertie
df_spec_clust <- df1[df1$cluster == Filter1,]
df_spec_prop<-df[df$Industries==Filter2,]
#Color and Icon for map
ai_colors <-c("red","gray","blue","orange","green","beige","darkgreen","lightgreen", "lightred", "darkblue","lightblue",
"purple","darkpurple","pink", "cadetblue","white","darkred", "lightgray","black")
clust_colors <- ai_colors[df$cluster]
icons <- awesomeIcons(
icon = 'ios-close',
iconColor = 'black',
library = 'ion',
markerColor = clust_colors)
leafIcons <- icons(
iconUrl = ifelse(df1$Industries,
"https://image.flaticon.com/icons/svg/542/542461.svg"
),
iconWidth = 45, iconHeight = 40,
iconAnchorX = 25, iconAnchorY = 12)
html_legend <- "<img src='https://image.flaticon.com/icons/svg/542/542461.svg'>"
# Map for specific cluster and propertie
if(nrow(df_spec_clust)>0){
clust_colors <- ai_colors[df_spec_clust$cluster]
icons <- awesomeIcons(
icon = 'ios-close',
iconColor = 'black',
library = 'ion',
markerColor = clust_colors)
m1<-leaflet(df_spec_clust) %>% addTiles() %>%
addMarkers(~Longitude, ~Latitude, icon = leafIcons) %>%
addAwesomeMarkers(leaflet(df_spec_prop) %>% addTiles(), lat=~df_spec_prop$Latitude, lng = ~df_spec_prop$Longitude, icon= icons,label=~cluster)#%>%
plot1<-m1} else plot1 <- NULL
return(list(
"Plot1" = plot1,
"Data" = data_table_1,
"Data1" = data_table
))
}
ui <- bootstrapPage(
navbarPage(theme = shinytheme("flatly"), collapsible = TRUE,
"Cl",
tabPanel("Solution",
sidebarLayout(
sidebarPanel(
tags$b(h3("Choose the cluster number?")),
sliderInput("Slider", h5(""),
min = 2, max = 4, value = 3),
selectInput("Filter1", label = h4("Select just one cluster to show"),""),
selectInput("Filter2",label=h4("Select the cluster property designated above"),""),
textInput("Filter3", label = h4("Distance is:"), value = "Enter text..."),
),
mainPanel(
tabsetPanel(
tabPanel("Solution", (leafletOutput("Leaf",width = "95%", height = "600"))))),
))))
server <- function(input, output, session) {
Modelcl<-reactive({
function.cl(df,input$Slider,input$Filter1,input$Filter2,input$Filter3)
})
output$Leaf <- renderLeaflet({
Modelcl()[[1]]
})
observeEvent(c(df,input$Slider),{
abc <- req(Modelcl()$Data)
updateSelectInput(session,'Filter1',
choices=c(sort(unique(abc$cluster))))
})
observeEvent(c(df,input$Slider,input$Filter1),{
abc <- req(Modelcl()$Data1) %>% filter(cluster == as.numeric(input$Filter1))
updateSelectInput(session,'Filter2',
choices = unique(abc$Industries))
})
}
shinyApp(ui = ui, server = server)
非常感谢!
我认为我对所有内容都理解正确,但是如果我错过了一些内容,请详细说明。
假设这段代码完成了您需要的距离计算:
#Coverage
coverage<-matrix(nrow=k,ncol=1)
for(i in 1:k){
aux_dist<-distm(rbind(subset(coordinates,cluster==i),center_mass[i,])[,2:1])
coverage[i,]<-max(aux_dist[nclusters[i,1]+1,])}
coverage<-cbind(coverage,matrix(c(1:k),ncol=1))
colnames(coverage)<-c("Coverage_meters","cluster")
然后您需要返回coverage矩阵以及其他元素:
return(list(
"Plot1" = plot1,
"Data" = data_table_1,
"Data1" = data_table,
"Cover" = coverage
))
并且索引依赖于服务器中input$Filter1
的矩阵:
output$dist <- renderText({
cover <- data.frame(Modelcl()[[4]])
cover$Coverage_meters[cover$cluster == input$Filter1]
})
请注意,您不需要input$Filter3
。仅当您期望用户输入距离时?但是,如果目标是显示距离,则需要使用以下内容替换该输入:
h4("Distance is:"),
textOutput("dist"),
然后我们得到这样的东西:
编辑
要索引Data1
而不是Cover
,请使用以下renderText
:
output$dist <- renderText({
data1 <- data.frame(Modelcl()[[3]])
data1$Coverage_meters[data1$cluster == input$Filter1 & data1$Industries == input$Filter2]
})
完整代码:
library(shiny)
library(ggplot2)
library(rdist)
library(geosphere)
library(shinythemes)
library(leaflet)
function.cl<-function(df,k,Filter1,Filter2){
df<-structure(list(Industries = c(1,2,3,4,5,6),
Latitude = c(-23.8, -23.8, -23.9, -23.7, -23.7,-23.7),
Longitude = c(-49.5, -49.6, -49.7, -49.8, -49.6,-49.9),
Waste = c(526, 350, 526, 469, 534, 346)), class = "data.frame", row.names = c(NA, -6L))
#clusters
coordinates<-df[c("Latitude","Longitude")]
d<-as.dist(distm(coordinates[,2:1]))
fit.average<-hclust(d,method="average")
clusters<-cutree(fit.average, k)
nclusters<-matrix(table(clusters))
df$cluster <- clusters
#Center of mass
center_mass<-matrix(nrow=k,ncol=2)
for(i in 1:k){
center_mass[i,]<-c(weighted.mean(subset(df,cluster==i)$Latitude,subset(df,cluster==i)$Waste),
weighted.mean(subset(df,cluster==i)$Longitude,subset(df,cluster==i)$Waste))}
coordinates$cluster<-clusters
center_mass<-cbind(center_mass,matrix(c(1:k),ncol=1))
#Coverage
coverage <- matrix(nrow = k, ncol = 1)
for (i in 1:k) {
aux_dist <-
distm(rbind(subset(coordinates, cluster == i), center_mass[i, ])[, 2:1])
coverage[i, ] <- max(aux_dist[nclusters[i, 1] + 1, ])
}
coverage <- cbind(coverage, matrix(c(1:k), ncol = 1))
colnames(coverage) <- c("Coverage_meters", "cluster")
#Sum of Waste from clusters
sum_waste<-matrix(nrow=k,ncol=1)
for(i in 1:k){
sum_waste[i,]<-sum(subset(df,cluster==i)["Waste"])
}
sum_waste<-cbind(sum_waste,matrix(c(1:k),ncol=1))
colnames(sum_waste)<-c("Potential_Waste_m3","cluster")
#Tables to join information above and generate df1
data_table <- Reduce(merge, list(df, coverage,sum_waste))
data_table <- data_table[order(data_table$cluster, as.numeric(data_table$Industries)),]
data_table_1 <- aggregate(. ~ cluster + Coverage_meters + Potential_Waste_m3, data_table[,c(1,5,6,7)], toString)
df1<-as.data.frame(center_mass)
colnames(df1) <-c("Latitude", "Longitude", "cluster")
#specific cluster and specific propertie
df_spec_clust <- df1[df1$cluster == Filter1,]
df_spec_prop<-df[df$Industries==Filter2,]
#Color and Icon for map
ai_colors <-c("red","gray","blue","orange","green","beige","darkgreen","lightgreen", "lightred", "darkblue","lightblue",
"purple","darkpurple","pink", "cadetblue","white","darkred", "lightgray","black")
clust_colors <- ai_colors[df$cluster]
icons <- awesomeIcons(
icon = 'ios-close',
iconColor = 'black',
library = 'ion',
markerColor = clust_colors)
leafIcons <- icons(
iconUrl = ifelse(df1$Industries,
"https://image.flaticon.com/icons/svg/542/542461.svg"
),
iconWidth = 45, iconHeight = 40,
iconAnchorX = 25, iconAnchorY = 12)
html_legend <- "<img src='https://image.flaticon.com/icons/svg/542/542461.svg'>"
# Map for specific cluster and propertie
if (nrow(df_spec_clust) > 0) {
clust_colors <- ai_colors[df_spec_clust$cluster]
icons <- awesomeIcons(
icon = 'ios-close',
iconColor = 'black',
library = 'ion',
markerColor = clust_colors
)
m1 <- leaflet(df_spec_clust) %>% addTiles() %>%
addMarkers( ~ Longitude, ~ Latitude, icon = leafIcons) %>%
addAwesomeMarkers(
leaflet(df_spec_prop) %>% addTiles(),
lat = ~ df_spec_prop$Latitude,
lng = ~ df_spec_prop$Longitude,
icon = icons,
label = ~ cluster
)#%>%
plot1 <- m1
} else
plot1 <- NULL
return(list(
"Plot1" = plot1,
"Data" = data_table_1,
"Data1" = data_table,
"Cover" = coverage
))
}
ui <- bootstrapPage(
navbarPage(theme = shinytheme("flatly"), collapsible = TRUE,
"Cl",
tabPanel("Solution",
sidebarLayout(
sidebarPanel(
tags$b(h3("Choose the cluster number?")),
sliderInput("Slider", h5(""),
min = 2, max = 4, value = 3),
selectInput("Filter1", label = h4("Select just one cluster to show"),""),
selectInput("Filter2",label=h4("Select the cluster property designated above"),""),
h4("Distance is:"),
textOutput("dist"),
),
mainPanel(
tabsetPanel(
tabPanel("Solution", (leafletOutput("Leaf",width = "95%", height = "600"))))),
))))
server <- function(input, output, session) {
Modelcl<-reactive({
function.cl(df,input$Slider,input$Filter1,input$Filter2)
})
output$Leaf <- renderLeaflet({
Modelcl()[[1]]
})
observeEvent(c(df,input$Slider),{
abc <- req(Modelcl()$Data)
updateSelectInput(session,'Filter1',
choices=c(sort(unique(abc$cluster))))
})
observeEvent(c(df,input$Slider,input$Filter1),{
abc <- req(Modelcl()$Data1) %>% filter(cluster == as.numeric(input$Filter1))
updateSelectInput(session,'Filter2', choices = unique(abc$Industries))
})
output$dist <- renderText({
cover <- data.frame(Modelcl()[[4]])
cover$Coverage_meters[cover$cluster == input$Filter1]
})
}
shinyApp(ui = ui, server = server)
问题的解决方法
library(shiny)
library(ggplot2)
library(rdist)
library(geosphere)
library(shinythemes)
library(leaflet)
function.cl<-function(df,k,Filter1,Filter2,Filter3){
df<-structure(list(Industries = c(1,2,3,4,5,6),
Latitude = c(-23.8, -23.8, -23.9, -23.7, -23.7,-23.7),
Longitude = c(-49.5, -49.6, -49.7, -49.8, -49.6,-49.9),
Waste = c(526, 350, 526, 469, 534, 346)), class = "data.frame", row.names = c(NA, -6L))
k=3
#clusters
coordinates<-df[c("Latitude","Longitude")]
d<-as.dist(distm(coordinates[,2:1]))
fit.average<-hclust(d,method="average")
clusters<-cutree(fit.average, k)
nclusters<-matrix(table(clusters))
df$cluster <- clusters
#Center of mass
center_mass<-matrix(nrow=k,ncol=2)
for(i in 1:k){
center_mass[i,]<-c(weighted.mean(subset(df,cluster==i)$Latitude,subset(df,cluster==i)$Waste),
weighted.mean(subset(df,cluster==i)$Longitude,subset(df,cluster==i)$Waste))}
coordinates$cluster<-clusters
center_mass<-cbind(center_mass,matrix(c(1:k),ncol=1))
#Coverage
coverage<-matrix(nrow=k,ncol=1)
for(i in 1:k){
aux_dist<-distm(rbind(subset(coordinates,cluster==i),center_mass[i,])[,2:1])
coverage[i,]<-max(aux_dist[nclusters[i,1]+1,])}
coverage<-cbind(coverage,matrix(c(1:k),ncol=1))
colnames(coverage)<-c("Coverage_meters","cluster")
#Sum of Waste from clusters
sum_waste<-matrix(nrow=k,ncol=1)
for(i in 1:k){
sum_waste[i,]<-sum(subset(df,cluster==i)["Waste"])
}
sum_waste<-cbind(sum_waste,matrix(c(1:k),ncol=1))
colnames(sum_waste)<-c("Potential_Waste_m3","cluster")
#Tables to join information above and generate df1
data_table <- Reduce(merge, list(df, coverage,sum_waste))
data_table <- data_table[order(data_table$cluster, as.numeric(data_table$Industries)),]
data_table_1 <- aggregate(. ~ cluster + Coverage_meters + Potential_Waste_m3, data_table[,c(1,5,6,7)], toString)
df1<-as.data.frame(center_mass)
colnames(df1) <-c("Latitude", "Longitude", "cluster")
#specific cluster and specific propertie
df_spec_clust <- df1[df1$cluster == Filter1,]
df_spec_prop<-df[df$Industries==Filter2,]
#Color and Icon for map
ai_colors <-c("red","gray","blue","orange","green","beige","darkgreen","lightgreen", "lightred", "darkblue","lightblue",
"purple","darkpurple","pink", "cadetblue","white","darkred", "lightgray","black")
clust_colors <- ai_colors[df$cluster]
icons <- awesomeIcons(
icon = 'ios-close',
iconColor = 'black',
library = 'ion',
markerColor = clust_colors)
leafIcons <- icons(
iconUrl = ifelse(df1$Industries,
"https://image.flaticon.com/icons/svg/542/542461.svg"
),
iconWidth = 45, iconHeight = 40,
iconAnchorX = 25, iconAnchorY = 12)
html_legend <- "<img src='https://image.flaticon.com/icons/svg/542/542461.svg'>"
# Map for specific cluster and propertie
if(nrow(df_spec_clust)>0){
clust_colors <- ai_colors[df_spec_clust$cluster]
icons <- awesomeIcons(
icon = 'ios-close',
iconColor = 'black',
library = 'ion',
markerColor = clust_colors)
m1<-leaflet(df_spec_clust) %>% addTiles() %>%
addMarkers(~Longitude, ~Latitude, icon = leafIcons) %>%
addAwesomeMarkers(leaflet(df_spec_prop) %>% addTiles(), lat=~df_spec_prop$Latitude, lng = ~df_spec_prop$Longitude, icon= icons,label=~cluster)#%>%
plot1<-m1} else plot1 <- NULL
mydf<- merge(df,df1,by = c("cluster"), suffixes = c("_df","_df1"))
(mydf$distances <- purrr::pmap_dbl(.l = list(mydf$Longitude_df,
mydf$Latitude_df,
mydf$Longitude_df1,
mydf$Latitude_df1),
.f = ~distm(c(..1,..2),c(..3,..4))))
return(list(
"Plot1" = plot1,
"Data" = data_table_1,
"Data1" = data_table,
"Cover" = mydf
))
}
ui <- bootstrapPage(
navbarPage(theme = shinytheme("flatly"), collapsible = TRUE,
"Cl",
tabPanel("Solution",
sidebarLayout(
sidebarPanel(
tags$b(h3("Choose the cluster number?")),
sliderInput("Slider", h5(""),
min = 2, max = 4, value = 3),
selectInput("Filter1", label = h4("Select just one cluster to show"),""),
selectInput("Filter2",label=h4("Select the cluster property designated above"),""),
h4("Distance is:"),
textOutput("dist"),
),
mainPanel(
tabsetPanel(
tabPanel("Solution", (leafletOutput("Leaf",width = "95%", height = "600"))))),
))))
server <- function(input, output, session) {
Modelcl<-reactive({
function.cl(df,input$Slider,input$Filter1,input$Filter2,input$Filter3)
})
output$Leaf <- renderLeaflet({
Modelcl()[[1]]
})
observeEvent(c(df,input$Slider),{
abc <- req(Modelcl()$Data)
updateSelectInput(session,'Filter1',
choices=c(sort(unique(abc$cluster))))
})
observeEvent(c(df,input$Slider,input$Filter1),{
abc <- req(Modelcl()$Data1) %>% filter(cluster == as.numeric(input$Filter1))
updateSelectInput(session,'Filter2',
choices = unique(abc$Industries))
})
output$dist <- renderText({
cover <- data.frame(Modelcl()[[4]])
cover$distances[cover$cluster == input$Filter1 & cover$Industries == input$Filter2]
})
}
shinyApp(ui = ui, server = server)