0

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)
Antonio
  • 1,091
  • 7
  • 24

1 Answers1

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)

enter image description here

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.

Rolando Tamayo
  • 286
  • 2
  • 8
  • Thank you very much for the reply Rolando. I generated the scatterplot by excel, however the shapefile (file .dbf) didn't work. Did it work for you? – Antonio Jun 25 '20 at 12:16
  • Hi Jose, I provided it again and it did not work. I Change the answer so that instead of the ".dbf" file it reads the ".shp" file. But not the ".shp.xml" file but only ".shp" and now it works. I don't know why yesterday it worked with ".dbf" – Rolando Tamayo Jun 25 '20 at 15:34
  • Unfortunately I still haven't succeeded. I tested this new code of yours as you said, but the scatterplot is not being generated. Could test again, strange I was not getting. Only excel is working. – Antonio Jun 25 '20 at 15:50
  • How strange for me it is working well, as in the image I added. Also I added the parameter I accepted the code but it really doesn't make any difference. Do you receive an error or does the graph just not appear? – Rolando Tamayo Jun 25 '20 at 16:14
  • Please try to take this code that you entered and play it on the console, it is giving an error. I want to see if solving this appears the scatter plot. – Antonio Jun 25 '20 at 16:25
  • I saw that you edited the code. Executed, however when I insert the .shp file, it gives the following error: ```Warning: Error in ogrInfo: Cannot open layer [No stack trace available]```. It is interesting that yours works. – Antonio Jun 25 '20 at 18:23
  • Read this [group](https://groups.google.com/forum/#!topic/shiny-discuss/FtI76rdvoHI), I note that we need you need to upload 3 necessary files (`shp` `shx`, `dbf`). I have re-edited the code again. Please try it. – Rolando Tamayo Jun 25 '20 at 20:00
  • Now it worked. So, I always need to insert these three files to work through the shapefile, right? Thank you so much friend for helping me. – Antonio Jun 25 '20 at 20:26
  • That is good. At least, perhaps in other applications more files are needed than those that accompany the shp – Rolando Tamayo Jun 25 '20 at 21:34
  • Understood. Thank you very much for your assistance. – Antonio Jun 25 '20 at 22:58
  • Hi Rolando, any idea for the question: https://stackoverflow.com/questions/62761896/questions-regarding-the-stplanr-package-in-r – Antonio Jul 06 '20 at 20:00