Плотно работает при использовании ggplot (), но не при использовании plot_ly () на блестящем сервере - PullRequest
0 голосов
/ 17 января 2019

У меня проблема с использованием Plotly на моем блестящем сервере. У меня есть приложение для кластеризации, в которое я добавляю файл данных, и вы можете выполнять кластеризацию двух и трех переменных. Первая вкладка - кластеризация двух переменных. Я использую ggplot() для создания графика, а затем использую функцию Plotly ggplotly(), чтобы сделать его сюжетным объектом для включения интерактивности. Это хорошо на странице приложения.

Проблема здесь заключается в построении кластеров из трех переменных. Вместо ggplot(), а затем ggploty() я использую функцию Плотли plot_ly(). Это позволяет мне передавать переменные x, y и z. Это работает как чудо на моей локальной машине, но когда на блестящем сервере я получаю эту ошибку Error: An error has occurred. Check your logs or contact the app author for clarification. Я открываю свои журналы и выполняю жесткое обновление приложения, никаких журналов не отображается. Версии моего пакета одинаковы как для моего блестящего сервера, так и для моей локальной машины. Ошибка не все говорит здесь, и я пытался погуглить, но я не понимаю, где.

Вот код:

server.R

## Needed Lib's
library(shiny)
library(ggplot2)
library(plotly)
library(DT)
library(cluster) 

## Initiate the severer
shinyServer(
  function(input, output, session) {

    ## Display the text that describes why to use this app/method for grouping
    output$text <- renderText({
    ## Let the user know which tab they have selected
    {paste0("You are viewing the \"", input$ClusterChoice, "\"")}
    })

    ## Display the text that describes why to use this app/method for grouping
    output$why_text <- renderText({
      ## Let the user know which tab they have selected
      "This is why"
    })

    # Variable #1
    output$varselect1 <- renderUI({
      selectInput("var1", label = "Select first variable for clustering:",
                  choices = names(dataset()), selected = names(dataset())[1])  
    })
    # Variable #2
    output$varselect2 <- renderUI({
      selectInput("var2", label = "Select second variable for clustering:",
                  choices = names(dataset()), selected = names(dataset())[2])  
    })

    ## Clustering with third variable
    # Variable #1
    output$varselect3 <- renderUI({
      selectInput("var3", label = "Select third variable for clustering (only works in Multiple Variable Tiering Tab):",
                  choices = names(dataset()), selected = names(dataset())[3])  
    })

    ## Read in the data
    dataset <- reactive({
      infile <- input$datafile
      if (is.null(infile)) {
        return(NULL)
      }
      else {read.csv(infile$datapath)}
    })

    ## Compute the K means algo
    compute_kmeans <- reactive({
      # Choose between simple K means or a more complex K means with third variable
      if (input$ClusterChoice == 'Two Variable Tiering') {
        data <- subset(dataset(), select = c(input$var1, input$var2))
        # Scale the data. Using "standardized" here. This will center and then scale the data 
        #data <- scale(data, center = TRUE)
        # Change some columns names
        colnames(data) <- c('x', 'y')
        data <- na.omit(data)
        # Set the seed
        set.seed(111)
        # Cluster
        Kclust <- kmeans(data, input$k)
        # Save results to a list
        kmean.result <- list(kmean.result = data.frame(data, cluster = as.factor(Kclust$cluster)))

        return(kmean.result)
      }
      # K means with third variable 
      else { (input$ClusterChoice == 'Multiple Variable Tiering') 
        three_var_data <- subset(dataset(), select = c(input$var1, input$var2, input$var3))
        # Scale the data. Using "standardized" here. This will center and then scale the data 
        #three_var_data <- scale(three_var_data, center = TRUE)
        three_var_data <- na.omit(three_var_data)
        # Set the seed
        set.seed(111)
        # Cluster
        Kclust <- kmeans(three_var_data, input$k)
        kmean.result <- list(kmean.result = data.frame(three_var_data, cluster = as.factor(Kclust$cluster)))

        return(kmean.result)
      }
    })

    ## Create a dataframe of the K means & K means with third variable results
    kmeans_results <- reactive({
      # For only two variables 
      if (input$ClusterChoice == 'Two Variable Tiering') {
        # Call the method that computes the k means
        data <- compute_kmeans()
        # Save the results into a df 
        results <- data$kmean.result
        results_df <- data.frame(results)
        colnames(results_df) <- c(input$var1, input$var2, 'Grouping')

        return(results_df)
      }
      # For more than two variables
      else { (input$ClusterChoice == 'Multiple Variable Tiering')
        # Call the method that computes the k means with third variable
        three_var_data <- compute_kmeans()
        # Save the results into a df 
        three_var_results <- three_var_data$kmean.result
        three_var_results_df <- data.frame(three_var_results)
        colnames(three_var_results_df) <- c(input$var1, 
                                   input$var2, 
                                   input$var3,
                                   'Grouping')

        return(three_var_results_df)
      }
    })
    ## Results of each K means & K means with third variable
    master_results <- reactive({
      # Call the method that stores the raw input data
      data <- dataset()
      # For only two variables
      if(input$ClusterChoice == 'Two Variable Tiering') {
        # Call the method that stores the K means results
        kmean_results <- kmeans_results()
        # Merge the K means results with the raw input data
        results <- merge(kmean_results, data)
        results <- results[!duplicated(results), ]

        return(results)
      }
      # For more than two variables
      else { (input$ClusterChoice == 'Multiple Variable Tiering')
        # Call the method that stores the K means with third variable results
        kmean_three_var_results <- kmeans_results()
        # Merge the K means with third variable results with the raw input data
        three_var_resutls <- merge(kmean_three_var_results, data)
        three_var_resutls <- three_var_resutls[!duplicated(three_var_resutls), ]

        return(three_var_resutls)
      }
    })

    ## Plot the K means results
    output$plot <- renderPlotly({
      graphics.off()
      pdf(NULL)
      # For only two variables
      if (input$ClusterChoice == 'Two Variable Tiering') {
        # Call the K means results method
        results <- master_results()
        # Change the x & y variables so we can call it in the tool-tip
        x_axis <- results[[input$var1]]
        y_axis <- results[[input$var2]]
        # Plot
        plot <- ggplot(data = results, 
                        aes(x = x_axis, 
                            y = y_axis, 
                            color = Grouping,
                            name = Markets)) +
                       geom_point(size = 2) + 
                       ggtitle("Grouping Results") +
                       labs(x = input$var1, y = input$var2)
        # Use Plotly for interactivity
        plotly_plot <- ggplotly(plot)

        return(plotly_plot)
      }
      # For more than two variables
      else if (input$ClusterChoice == 'Multiple Variable Tiering')
        # Call the K means and third variable 
        three_var_resutls <- master_results()
        # Change x, y, & z variables so we can call it in the tool-tip
        x_axis <- three_var_resutls[[input$var1]]
        y_axis <- three_var_resutls[[input$var2]]
        z_axis <- three_var_resutls[[input$var3]]
        # Plot (using Plotly for interactivity)
        three_var_plot <- plot_ly(three_var_resutls, 
                            x = x_axis, 
                            y = y_axis, 
                            z = z_axis, 
                            color = factor(three_var_resutls$Grouping),
                            text = ~paste('Markets:', three_var_resutls$Markets,
                                          '<br>Grouping:', three_var_resutls$Grouping)) %>%
                    add_markers() %>%
                    layout(title = 'Grouping Results',
                           scene = list(xaxis = list(title = input$var1),
                                        yaxis = list(title = input$var2),
                                        zaxis = list(title = input$var3)))

        return(three_var_plot)
    })

    ## Render the K means and K means with third variable results to a data table
    output$cluster_table <- DT::renderDataTable({
      # For only two variables
      if (input$ClusterChoice == 'Two Variable Tiering') {
      # Call results method
      results <- master_results()
      # Render data table
      datatable(results,
                # Get rid of row indexes
                rownames = FALSE,
                # Enable downloading options
                extensions = 'Buttons',
                options = list(
                  dom = "Blfrtip",
                  buttons = 
                   list("copy", list(
                     extend = "collection",
                      buttons = c("csv", "excel", "pdf"),
                      text = "Download")),
                  lengthMenu = list(c(10, 20, -1),
                                    c(10, 20, "All")),
                  pageLength = 10))
      }
      else if (input$ClusterChoice == 'Multiple Variable Tiering') {
        # Call results method
        results_three_var <- master_results()
        # Render data table
        datatable(results_three_var,
                  # Get rid of row indexes
                  rownames = FALSE,
                  # Enable downloading options
                  extensions = 'Buttons',
                  options = list(
                    dom = "Blfrtip",
                    buttons = 
                      list("copy", list(
                        extend = "collection",
                        buttons = c("csv", "excel", "pdf"),
                        text = "Download")),
                    lengthMenu = list(c(10, 20, -1),
                                      c(10, 20, "All")),
                    pageLength = 10))
      }
    })
  }    
)

ui.r

## Needed Lib's
library(shiny)
library(plotly)

## Start the UI renderer
shinyUI(
  pageWithSidebar(

    ## The TITLE!
    headerPanel("Grouping Data Together"),

    ## This is where the up-loader and drop downs live
    sidebarPanel(
      fileInput('datafile', 
                'Choose CSV file',
                accept=c('text/csv', 'text/comma-separated-values,text/plain')),
      uiOutput("varselect1"),
      uiOutput("varselect2"),
      uiOutput("varselect3"),
      numericInput('k', 'Number of clusters', value = 3, min = 1, step = 1)),

    ## The main panel where all the shit happens 
    mainPanel(
      textOutput("text"),
      tabsetPanel(id = 'ClusterChoice', 
                  tabPanel("Two Variable Tiering", value = 'Two Variable Tiering'),
                  tabPanel("Multiple Variable Tiering", value = 'Multiple Variable Tiering'),
                  tabPanel("Why Do It This Way?", value = "Why Do It This Way?")
                  ),

      ## Description of this app
      h2("Description"),
      p("This tool's main functionality is to quickly put your data into groups. The file that is being uploaded
        should only be the data that you want to group together. For example, if you have data that is broken out 
        by Markets (DMA) and you want to group those Markets into similar groupings you should upload all data 
        that you think is important to those groupings. Then via the drop downs you can select the 2 or 3 variables
        you think best represents the groupings."),
      ## The tabs
      h2("The Different Tabs"),
      p("Tab #1: This tab is only when you want to use 2 variables in your data to create the groupings."),
      p("Tab #2: This tab is only when you want to use 3 variables in your data to create the groupings."),
      ## Instructions for using this app
      h2("Instructions"),
      p("Please follow these instructions to create your groupings."),
      p("1. Upload a data file (.csv) that will be used for making your groups.
        The first row in the .csv file should be the column headers of the data. 
        The first column in the .csv file should be where your data starts.
        THERE SHOULD BE NO 'BUFFERS' AROUND YOUR DATA FILE, i.e. empty rows and columns."),
      p("2. Pick the variables you want to create the groupings off of via the drop-downs"),
      p("3. Indicate the desired number of groups via the last drop-down."),
      ## The plot instructions 
      h2("Visualizing Your Grouped Data"),
      p("You can download the plot as a .png file by hovering over the plot and selecting the 
        camera icon in the upper right hand side of the plot."),
      # Plotly function that links the UI to the Server
      plotlyOutput('plot', height = 700),
      ## The grouping data table instructions
      h2("The Groupings"),
      p("Instructions for downloading data:"),
      p("1. To download the data use the drop-down below, labeled 'Show entries', to show 'All' entries."),
      p("2. Click the 'Download' button and then select the type of file (PDF, excel, csv)."),
      p("3. (Optional) You can copy the data that is shown to your clipboard is paste it into an excel/csv document."),
      # JS DataTable function that links the UI to the Server
      DT::dataTableOutput("cluster_table"))
  )
)
...