我在闪亮的服务器上使用Plotly时遇到问题。我有一个群集应用程序,在其中引入了一个数据文件,您可以执行两个变量和三个变量的群集。第一个选项卡是两个变量聚类。我使用ggplot()
创建绘图,然后使用Plotly的ggplotly()
函数使其成为可绘图对象以启用交互性。这在应用程序页面上呈现良好。
这里的问题是绘制三个变量聚类时。我使用的是Plotly函数ggplot()
,而不是ggploty()
然后是plot_ly()
。这使我可以传递x,y和z变量。它在本地计算机上就像一个超级按钮一样工作,但是在闪亮的服务器上出现此错误Error: An error has occurred. Check your logs or contact the app author for clarification.
时,我打开日志并对应用程序进行了强制刷新,没有日志显示。我的闪亮服务器和本地计算机的软件包版本都相同。错误不是每一个都在这里告诉我,我已经尝试在Google周围搜索,但是我什么也没找到。
代码如下:
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"))
)
)