问题
The codes below are working normally, the first code is generating a scatterplot by Shapefile and the second code is generating via Excel, both via fileInput. For simulation the data can be obtained through the following website: https://github.com/JovaniSouza/JovaniSouza5/blob/master/shapefile.rar (shapefile)
https://github.com/JovaniSouza/JovaniSouza5/blob/master/Example.xlsx (excel)
The problem I am having is that I am not able to unify these codes, since I want to have only one code to generate the scatter plot and not two, could you help me solve this problem? In other words, I want to make it easier for the user to choose between using shapefile or excel data to generate the scatterplot in one code.
Thank you very much!
SHAPEFILE
library(shiny)
library(ggplot2)
library(shinythemes)
library(rdist)
library(geosphere)
library(rgdal)
function.cl<-function(k,path,filename){
print(dir(path))
shape<-readOGR(dsn=path,layer=filename)
df<-shape@data
#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
#all cluster data df1 and specific cluster df_spec_clust
df1<-df[c("Latitude","Longitude")]
df1$cluster<-as.factor(clusters)
#Colors
my_colors <- rainbow(length(df1$cluster))
names(my_colors) <- df1$cluster
#Scatter Plot for all clusters
g <- ggplot(data = df1, aes(x=Longitude, y=Latitude, color=cluster)) +
geom_point(aes(x=Longitude, y=Latitude), size = 4) +
scale_color_manual("Legend", values = my_colors)
plotGD <- g
return(list(
"Plot" = plotGD
))
}
ui <- bootstrapPage(
navbarPage(theme = shinytheme("flatly"), collapsible = TRUE,
"Cl",
tabPanel("Solution",
fileInput("shp", h3("Shapefile Import"), multiple = TRUE, accept = c('.shp', '.dbf','.sbn', '.sbx', '.shx', '.prj')),
sidebarLayout(
sidebarPanel(
sliderInput("Slider", h5(""),
min = 2, max = 4, value = 3),
),
mainPanel(
tabsetPanel(
tabPanel("Solution", plotOutput("ScatterPlot"))))
))))
server <- function(input, output, session) {
Modelcl <- eventReactive(c(input$shp, input$Slider),{
req(input$shp)
tmpdir <- tempdir()
on.exit(unlink(tmpdir))
filename <- substr(input$shp$name[1],1,nchar(input$shp$name[1])-4)
file.copy(input$shp$datapath,file.path(tmpdir,input$shp$name) )
function.cl(input$Slider,tmpdir,filename)
})
output$ScatterPlot <- renderPlot({
Modelcl()[[1]]
})
}
shinyApp(ui = ui, server = server)
EXCEL
library(shiny)
library(ggplot2)
library(shinythemes)
library(rdist)
library(geosphere)
library(rgdal)
function.cl<-function(df,k){
#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
#all cluster data df1 and specific cluster df_spec_clust
df1<-df[c("Latitude","Longitude")]
df1$cluster<-as.factor(clusters)
#Colors
my_colors <- rainbow(length(df1$cluster))
names(my_colors) <- df1$cluster
#Scatter Plot for all clusters
g <- ggplot(data = df1, aes(x=Longitude, y=Latitude, color=cluster)) +
geom_point(aes(x=Longitude, y=Latitude), size = 4) +
scale_color_manual("Legend", values = my_colors)
plotGD <- g
return(list(
"Plot" = plotGD
))
}
ui <- bootstrapPage(
navbarPage(theme = shinytheme("flatly"), collapsible = TRUE,
"Cl",
tabPanel("Solution",
fileInput("data", h3("Excel import")),
sidebarLayout(
sidebarPanel(
sliderInput("Slider", h5(""),
min = 2, max = 4, value = 3),
),
mainPanel(
tabsetPanel(
tabPanel("Solution", plotOutput("ScatterPlot"))))
))))
server <- function(input, output, session) {
v <- reactiveValues(df = NULL)
observeEvent(input$data, {
v$df <- read_excel(input$data$datapath)
})
Modelcl<-reactive({if (!is.null(v$df)) {
function.cl(v$df,input$Slider)
}
})
output$ScatterPlot <- renderPlot({
Modelcl()[[1]]
})
}
shinyApp(ui = ui, server = server)
回答1:
A simple solution is to check what type of file the user is loading and, depending on this, use the appropriate procedure. I did this in observeEvent(input$data,.
SHAPEFILE AND EXCEL
library(shiny)
library(ggplot2)
library(shinythemes)
library(rdist)
library(openxlsx) #I use this library to read exel files.
library(geosphere)
library(rgdal)
function.cl<-function(df,k){
#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
#all cluster data df1 and specific cluster df_spec_clust
df1<-df[c("Latitude","Longitude")]
df1$cluster<-as.factor(clusters)
#Colors
my_colors <- rainbow(length(df1$cluster))
names(my_colors) <- df1$cluster
#Scatter Plot for all clusters
g <- ggplot(data = df1, aes(x=Longitude, y=Latitude, color=cluster)) +
geom_point(aes(x=Longitude, y=Latitude), size = 4) +
scale_color_manual("Legend", values = my_colors)
plotGD <- g
return(list(
"Plot" = plotGD
))
}
ui <- bootstrapPage(
navbarPage(theme = shinytheme("flatly"), collapsible = TRUE,
"Cl",
tabPanel("Solution",
fileInput("data", h3("Excel or Shapefile import"),
accept = c(".xlsx",".shp",".shx",".dbf"),
multiple= T),
sidebarLayout(
sidebarPanel(
sliderInput("Slider", h5(""),
min = 2, max = 4, value = 3)
),
mainPanel(
tabsetPanel(
tabPanel("Solution", plotOutput("ScatterPlot"))))
))))
server <- function(input, output, session) {
v <- reactiveValues(df = NULL)
observeEvent(input$data, {
if(any(grepl(".xlsx",input$data$name))){
v$df <- read.xlsx(input$data$datapath) #Note that her I use read.xlsx form openxlsx.
}else if(any(grepl(".shp",input$data$name))){
shpDF <- input$data
failed <- F
if(!any(grepl(".shx",input$data$name))){
failed<-T
}
if(!any(grepl(".dbf",input$data$name))){
failed<-T
}
if(failed){
print("You Need 3 files, '*.shp', '*shx' and '*.dbf'")
}else{
prevWD <- getwd()
uploadDirectory <- dirname(shpDF$datapath[1])
setwd(uploadDirectory)
for (i in 1:nrow(shpDF)){
file.rename(shpDF$datapath[i], shpDF$name[i])
}
shpName <- shpDF$name[grep(x=shpDF$name, pattern="*.shp")]
shpName<-substr(shpName,1,nchar(shpName)-4)
setwd(prevWD)
shpFile<-readOGR(dsn=uploadDirectory,layer=shpName)
v$df<-shpFile@data
}
}else{
print("Wrong File")
}
})
Modelcl<-reactive({if (!is.null(v$df)) {
function.cl(v$df,input$Slider)
}
})
output$ScatterPlot <- renderPlot({
Modelcl()[[1]]
})
}
shinyApp(ui = ui, server = server)
Of course there are many other solutions such as using radio Buttons to let the user specify the type of file they want to load before doing so.
A recommendation would be to use the parameter acept from fileInput function, to limit the types of files that the user can upload.
来源:https://stackoverflow.com/questions/62567104/generate-scatterplot-both-by-shapefile-and-excel-in-shiny