Why does my app work locally, but not on shinyapps.io? - r

I'm trying to deploye my shiny app on shinyapps.io and I get this message :
"An error has occurred
The application failed to start (exited with code 1)."
I tried to commit setwd line and other stuff but yet I didn't find solution.
The issue might be a wrong file path ? Should I put the "read.csv" line into my server or ui function ?
Here is my code :
#setwd(dir = "/media/miles/MILES/Projets & Cours/Master_1/Semestre 2/lardjane/Shiny_app/Projet Shiny")
matches <- read.csv('./matches.csv', stringsAsFactors=FALSE, sep=",", header=TRUE)
matches <- matches[,c(3,6)]
#summary(matches)
matches$platformid <- as.factor(matches$platformid)
#levels(matches$platformid)
#install.packages('shiny')
library(shiny)
#install.packages('rsconnect')
library(rsconnect)
ui <- shinyUI(fluidPage(
# Give the page a title
titlePanel("Game time by server"),
# Generate a row with a sidebar
sidebarLayout(
# Define the sidebar with one input
sidebarPanel(
selectInput("region", "Server:",
choices=levels(matches$platformid)),
hr(),
selectInput(inputId = "n_breaks",
label = "Number of bins in histogram (approximate):",
choices = c(10, 20, 35, 50),
selected = 20),
hr(),
checkboxInput(inputId = "individual_obs",
label = strong("Show individual observations"),
value = FALSE),
checkboxInput(inputId = "density",
label = strong("Show density estimate"),
value = FALSE),
conditionalPanel(condition = "input.density == true",
sliderInput(inputId = "bw_adjust",
label = "Bandwidth adjustment:",
min = 0.2, max = 2, value = 1, step = 0.2)),
hr(),
helpText("Data from Kaggle (2014-2018) League of Legends Ranked Matches.")
),
# Create a spot for the barplot
mainPanel(
plotOutput("timePlot")
)
)
)
)
server <- function(input, output) {
# Fill in the spot we created for a plot
output$timePlot <- renderPlot({
# Render a histogramme
hist(matches[matches$platformid==input$region,2],
probability = TRUE,
breaks = as.numeric(input$n_breaks),
main = "Game Time",
ylab="",
xlab="Duration (seconds)")
if (input$individual_obs) {
rug(matches[matches$platformid==input$region,2])
}
if (input$density) {
dens <- density(matches[matches$platformid==input$region,2],
adjust = input$bw_adjust)
lines(dens, col = "blue")
}
})
}
shinyApp(ui = ui, server = server)
I would like to add one last request. I would like to display R code just below the plot. That can anyone can get access to both (app result and R code). Is that possible ?
Thank you in advance.

swd is not the way to solve this because of how the environments in Shiny (and R in general) work. When you launch Shiny you actually don't know what physical server your Shiny server is running on. So you need to use a generic solution.
Try this:
matches <- read.csv('./matches.csv',
stringsAsFactors=FALSE, sep=",", header=TRUE)

Per https://docs.rstudio.com/shinyapps.io/Storage.html, if the csv file is in the same location as the app, try :
matches <- read.csv('matches.csv', stringsAsFactors=FALSE, sep=",", header=TRUE)
However, I don't think this is your issue; I think the issue is in your rendering of the plot. You use the input$region to generate your histogram, but you don't provide a default value, so it starts as NULL, which causes an issue when you try to construct your histogram. You have 2 options to solve this.
Option 1 is to set a default value for input$region with:
selectInput("region", "Server:",
choices=levels(matches$platformid),
selected = levels(matches$platformid)[1]),
Option 2 is to use req() so that the histogram will not run if any of its required values are not truthy:
server <- function(input, output) {
# Fill in the spot we created for a plot
output$timePlot <- renderPlot({
req(input$region, input$n_breaks)
# Render a histogramme
hist(matches[matches$platformid==input$region,2],
probability = TRUE,
breaks = as.numeric(input$n_breaks),
main = "Game Time",
ylab="",
xlab="Duration (seconds)")
if (input$individual_obs) {
rug(matches[matches$platformid==input$region,2])
}
if (input$density) {
dens <- density(matches[matches$platformid==input$region,2],
adjust = input$bw_adjust)
lines(dens, col = "blue")
}
})
}

Related

R/Shiny: Subscript out of bounds error despite working in R

I've seen many people with issues like mine, but no answers have been helpful for my case.
I am using seurat for single cell data analysis and I'm trying to build a very simple web page for other individuals to query their gene expression.
I get a "subscript out of bounds" error while trying to run my Shiny app immediately on launch, despite it working in R.
In the console, it's immediately displaying -- Warning: Error in [[: subscript out of bounds. What am I doing wrong here?
library(shiny)
library(Seurat)
WholeEye <- readRDS("WholeEye.rds")
MG <- readRDS("MG.rds")
CMZ <- readRDS("CMZ.rds")
RPE <- readRDS("CMZ.rds")
ui <- fluidPage(
headerPanel('McFarlane scRNAseq'),
sidebarPanel(
textInput(inputId = 'celltype', label = "Choose a cell type. Eg. WholeEye, MG, RPE, CMZ", value = "MG", width = NULL, placeholder = NULL),
textInput(inputId = 'gene', label = "Choose a gene", value = "", width = NULL, placeholder = NULL)
),
mainPanel(
plotOutput(outputId = "FeaturePlot" )
)
)
server <- function(input, output) {
output$FeaturePlot <- renderPlot({
FeaturePlot(object = input$celltype, reduction = "umap", label = TRUE, min.cutoff = 0, features = input$gene)
})
}
shinyApp(ui = ui, server = server)
Try
output$FeaturePlot <- renderPlot({
req(input$celltype,input$gene)
FeaturePlot(object = get(input$celltype), reduction = "umap", label = TRUE, min.cutoff = 0, features = get(input$gene))
})

Preventing Shiny selectInput from evaluating prematurely when updating a reactive plot

I am working on a Shiny app that generates various plots and allows users to change graphing parameters. For this, I'm using a combination of selectInput, numericInput, and checkboxInput functions after the plot is generated (conditionalPanel). I packaged the code so that the data.frame used for the graph is calculated reactively (to allow flexible subsetting before plotting). Everything works great, but when I want to update some graphing parameters (such as colors to use via selectInput), the code breaks down because it evaluates prematurely before I select all the necessary colors (i.e. when there are 4 colors needed, code breaks right after selecting the first color).
I know about debounce function to delay evaluation, but I don't want to use it because:
I like the instant changes in the graph when I update other parameters
Selection of colors can take some time, so it is difficult to set a predetermined delay time/time interval
One solution can be to add an actionButton shown conditionally (along with other graphing parameters) to regulate the firing of the reactive input values (see below). This is not ideal because after changing parameters, I need to click on update to renew the graph. Also, I'm not sure how this would even work because the km_graph is already a reactive plot object. Alternatively, is there a solution for regulating selectInput specifically so that until all the colors selected, it is not evaluated?
I read several posts on this issue but I couldn't find a solution that works with the design of my code. I will try to write sections of my ui and server to give an idea of what I'm trying to do:
ui.R
# ...
mainPanel(
plotOutput("km_graph"),
# Conditional panel prompted only after the km_graph is generated
conditionalPanel(
condition = "output.km_graph" ,
checkboxInput("km_risk", label="Show risk table", F),
selectInput("km_medline", label = "Mark median survival",
selected = "hv",
choices = c("None" = "none",
"Horizontal-Vertical" = "hv",
"Vertical" = "v",
"Horizontal" = "h")),
sliderInput("km_xlim", label="days", value = 6000, min = 10, max=10000),
selectInput("km_pal", "Select colors", multiple = T,
selectize = T,
selected = "jco",
choices = list(`Pre-made palettes` = list("npg","aaas", "lancet", "jco",
"ucscgb", "UChicago",
"simpsons", "rickandmorty")
`Individual colors` = as.list(color_choices))
)
# Need to find a way to prevent evaluating before all the colors are selected for km_pal
# Maybe another actionButton() here to update graph after all the parameters are selected?
server.R
#...
# km_results() is the reactive object containing survival analysis results
# km_dat() is the reactive data frame used in the analyses
output$km_graph <- renderPlot({
survminer::ggsurvplot(km_results(), data = km_dat(),
pval = input$km_pval,
pval.method = input$km_pval,
risk.table = input$km_risk,
conf.int = input$km_confint,
surv.median.line = input$km_medline,
break.time.by = input$km_breaktime,
legend="right",
xlim=c(0, input$km_xlim),
palette = input$km_pal) ###### This breaks due to premature evaluation
})
Full Reprex
shinyApp(
ui = basicPage(
selectInput("dat", "Select data",
selected = "iris", choices = c("iris")),
actionButton("go", "Go!"),
plotOutput("plot"),
conditionalPanel(
h3("graphing options"),
condition = "output.plot",
checkboxInput("plot_point", "Show points", T),
selectizeInput("plot_colors", "Select colors", selected="jco",
choices = list(`premade`=list("jco", "npg"),
`manual`=list("red", "black", "blue")))
)
),
server = function(input, output) {
dat <- reactive({
if(input$dat == "iris") iris
})
output$plot <- renderPlot({
req(input$go)
ggpubr::ggscatter(dat(), "Sepal.Length", "Sepal.Width",
color="Species", palette=input$plot_colors)
})
}
)
Thanks for the insights!
I'm not 100% sure I fully understood, but you could for example pass the plot_colors input in a reactive variable that is triggered by an action button "Apply colors" ?
(you need to add multiple = TRUE in the selectizeInput's arguments)
Here is an example of code based on your reprex:
shinyApp(
ui = basicPage(
selectInput("dat", "Select data",
selected = "iris", choices = c("iris")),
actionButton("go", "Go!"),
plotOutput("plot"),
conditionalPanel(
h3("graphing options"),
condition = "output.plot",
checkboxInput("plot_point", "Show points", T),
selectizeInput("plot_colors",
"Select colors",
selected="jco",
multiple = TRUE,
choices = list(`premade`=list("jco", "npg"),
`manual`=list("red", "black", "blue"))),
actionButton(inputId = "apply", label = "Apply colors")
)
),
server = function(input, output) {
dat <- reactive({
if(input$dat == "iris") iris
})
params_curve <- shiny::eventReactive(eventExpr = input$apply,
{
return(list(colors = input$plot_colors))
},
ignoreNULL = F,
ignoreInit = F
)
output$plot <- renderPlot({
req(input$go)
ggpubr::ggscatter(dat(), "Sepal.Length", "Sepal.Width",
color="Species", palette=params_curve()$colors)
})
}
)
If you select "red", "black", and "blue", then the dimension of your plot_colors variable is 3. So, the plot is rendered.

Unable to render Gauge from Flexdashboard library in Shiny app

I am trying to create a Shiny app which
a) prompts user to upload a file which contains numeric data,
b) reads the file and assigns the data points to different variables,
c) calculates new variables from the captured variables
d) display a 'Gauge' using the calculated variables
The code successfully executes but the Gauge chart is not rendered properly. There is no error or warning message either. Instead, I am getting the following message:
"Input to asJSON(keep_vec_names=TRUE) is a named vector. In a future version of jsonlite, this option will not be supported, and named vectors will be translated into arrays instead of objects. If you want JSON object output, please use a named list instead. See ?toJSON."
And instead of the gauge output I am getting that tiny spec in the middle, as seen in the attached image.
The entire code is fairly long, hence providing just the relevant snippets of code.
Would really appreciate if you can help fix this.
library(shiny)
library(flexdashboard)
ui <- fluidPage(
tabPanel("Sensitivity Analysis",
sidebarLayout(
sidebarPanel(
uiOutput("Sensitivity_Analysis")
),
mainPanel(
gaugeOutput("sensitivity", width = "600px", height = "600px")
)
)
),
server <- function (input, output)
{
output$input_financials=renderUI({
fluidRow(fileInput("file1", "Choose CSV File",multiple = FALSE,accept = c("text/csv","text/comma-separated-values,text/plain",".csv")),
actionButton("process","Process"))})
data_input=reactiveValues()
observeEvent(input$process,{
file_input <- input$file1
if (is.null(file_input)) {
return(NULL)}
## File is read and all the inputs are assigned to variables
....
## Output for Gauge begins
output$sensitivity <- flexdashboard::renderGauge({
gauge_limit <- data_input$wc_value
data_input$cash_rel_dpo <- ## Formula for cash_del_dpo
data_input$cash_rel_dro <- ## Formula for cash_del_dro
data_input$cash_rel_dio <- ## Formula for cash_del_dio
data_input$wc_predicted_value <- (data_input$wc_predicted_value - data_input$cash_rel_dpo - data_input$cash_rel_dro - data_input$cash_rel_dio)
gauge(data_input$wc_predicted_value, min = 0, max = gauge_limit,
gaugeSectors(success = c(0, 10000),
warning = c(10001, 50000),
danger = c(50001, 1000000000))
)
})
shinyApp(ui = ui, server = server)
Screenshot of the output generated upon executing the code
There's a similar gauge in package billboarder, try this example:
library(shiny)
library(billboarder)
ui <- fluidPage(
tabPanel(
title = "Sensitivity Analysis",
sidebarLayout(
sidebarPanel(
fileInput("file1", "Choose CSV File",
multiple = FALSE,
accept = c("text/csv","text/comma-separated-values,text/plain",".csv")),
actionButton(inputId = "process", label = "Process (click here to refresh the gauge)")
),
mainPanel(
billboarderOutput("sensitivity", width = "400px", height = "400px")
)
)
)
)
server <- function (input, output) {
data_input <- reactiveValues(x = 0)
observeEvent(input$process, {
data_input$x <- sample.int(1e5, size = 1)
}, ignoreInit = TRUE)
## Output for Gauge begins
output$sensitivity <- renderBillboarder({
billboarder() %>%
bb_gaugechart(
value = data_input$x,
name = "Predicted value",
steps = c(1e4, 5e4, 1e5),
steps_color = rev(c("#FF0000","#F6C600", "#60B044"))
) %>%
bb_gauge(
min = 0, max = 1e5,
units = "",
label = list(
format = htmlwidgets::JS("function(value, ratio) {return d3.format(',')(value);}") # format value with thousand separator
),
width = 80
)
})
}
shinyApp(ui = ui, server = server)

Shiny Server unable to open connection to any shiny application

When I attempt to connect to any shiny application on my webserver I receive the following error:
ERROR: cannot open the connection
I am currently storing the application within the /srv/shiny-server folder on the server and the folder does currently have the correct read/write permissions. Earlier when I uploaded my application it ran without issue but I made several changes and when I updated the files I suddenly started getting this error. I tried rolling back all of the changes but the error persisted and so eventually I attempted uploading an example application from the Shiny Website and that also gets the same error.
Here is the code for the sample application I'm currently trying to get working but I do not think that it is the issue:
ui.R
library(shiny)
bootstrapPage(
selectInput(inputId = "n_breaks",
label = "Number of bins in histogram (approximate):",
choices = c(10, 20, 35, 50),
selected = 20),
checkboxInput(inputId = "individual_obs",
label = strong("Show individual observations"),
value = FALSE),
checkboxInput(inputId = "density",
label = strong("Show density estimate"),
value = FALSE),
plotOutput(outputId = "main_plot", height = "300px"),
# Display this only if the density is shown
conditionalPanel(condition = "input.density == true",
sliderInput(inputId = "bw_adjust",
label = "Bandwidth adjustment:",
min = 0.2, max = 2, value = 1, step = 0.2))
)
server.R
library(shiny)
function(input, output) {
output$main_plot <- renderPlot({
hist(faithful$eruptions,
probability = TRUE,
breaks = as.numeric(input$n_breaks),
xlab = "Duration (minutes)",
main = "Geyser eruption duration")
if (input$individual_obs) {
rug(faithful$eruptions)
}
if (input$density) {
dens <- density(faithful$eruptions,
adjust = input$bw_adjust)
lines(dens, col = "blue")
}
})
}
I opened up the logs for the application located in /var/log/shiny-server and it turned out that permission was being denied to the folder. After googling the problem I found this question which helped me solve the issue

R Shiny quantmod zoomChart and fixed coloring of points

I have a problem regarding shiny and the use of sliders, when displaying chart_Series and coloured lines . When I am using the slider from the right side, the color is chosen appropriately (mainly red dots). When I use the slider on left side (e.g. looking at the latest data) the color is not chosen appropriately (should be green). I seek for help and I'm thankful for any advise!
require(quantmod)
require(shiny)
getSymbols("YHOO")
data <- YHOO
data <- data[1:100,]
col_function <- rep("red",50)
col_function <- c(col_function, rep("green",50))
plot <- {
date_range <- index(data)
if (interactive()) {
options(device.ask.default = FALSE)
# Define UI
ui <- fluidPage(
titlePanel("Time:"),
sidebarLayout(
# Sidebar with a slider input
wellPanel(
tags$style(type="text/css", '#leftSlide { width:200px; float:left;}'),
id = "leftSlide",
sliderInput("Range", "Choose Date Range:",
min = first(date_range), max = last(date_range), value = c(first(date_range),last(date_range)))
),
mainPanel(
plotOutput("Plot", width = "150%", height = "500px")
)
)
)
# Server logic
server <- function(input, output) {
output$range <- renderPrint({ input$slider2 })
output$Plot <- renderPlot({
x_ti2 <- xts(rep(1, NROW(data)), order.by = index(data))
x_ti2[1, ] <- 0.5
chart_Series(data)
add_TA(x_ti2, col = col_function, pch = 9, type = 'p', cex = .7)
# Another way below, but the color function is still not working
#chart_Series(data["2017"], TA = 'add_TA(x_ti, col = col_function, pch = 15, type = "p", cex = .7); add_TA(x_ti2, col = "orange", pch = 9, type = "p", cex = .7)')
zoom_Chart(paste(input$Range, collapse = "::"))
})
observe({
print(input$Range)
})
}
shinyApp(ui, server)
}
}
plot
So, I found a workaround for my own problem:
as far as i can tell, shiny will edit the data, but not the coloring-vector (in respective pretty logical...). Therefore you'll have to tell shiny to update the range of the coloring as well.
First of all i transformed the coloring result to an xps-object. Then i added the x_ti2-variable to the original data-matrix and defined a variable with the input$range for your the col_function. The variable needs to part of the Global environment (such that shiny can use it). I hope this will solve some issues, if someone has a similiar problem.

Resources