Hello, I am trying to launch an R Shiny app and I keep running into this error,
rsconnect::deployApp('/Users/cameronwalker/Documents/BCM/Shiny')
── Preparing for deployment ─────────────────────────────────────────
✔ Re-deploying "shiny" using "server: shinyapps.io / username: cam-walker"
ℹ Looking up application with id "12271467"...
✔ Found application <https://cam-walker.shinyapps.io/shiny/>
ℹ Bundling 756 files:
...
ℹ Capturing R dependencies with renv
The following required packages are not installed:
- rstudio
Packages must first be installed before renv can snapshot them.
Use `renv::dependencies()` to see where this package is used in your project.
What do you want to do?
1: Snapshot, just using the currently installed packages.
2: Install the packages, then snapshot.
3: Cancel, and resolve the situation on your own.
Selection: 2
Error: package 'rstudio' is not available
I tried publishing the app from a different computer and even a server and got the same error. Here is my apps code.
library(shiny)
library(shinythemes)
library(readxl)
library(dplyr)
# Load and clean the data
samples_info <- read_excel(file.path(getwd(), "shiny-server", "samples_info.xlsx")) %>%
mutate(across(.cols = everything(), ~trimws(.)))
# Load cell types and replace underscores with spaces for display
cell_types <- readLines(file.path(getwd(), "shiny-server", "cell_types.txt"))
cell_types_display <- gsub("_", " ", cell_types)
# Create a named vector for the dropdown choices
cell_types_named <- setNames(cell_types, cell_types_display)
# Custom CSS for better aesthetics
custom_css <- "
body {
font-family: 'Arial', sans-serif;
}
.sidebar {
background-color: #f7f7f7;
border-right: 1px solid #ddd;
padding: 20px;
}
.main-panel {
padding: 20px;
}
.tissue-description {
color: #333;
font-weight: bold;
margin-top: 20px;
font-size: 18px;
}
.no-description {
color: red;
font-weight: bold;
margin-top: 20px;
}
.iframe-container {
margin-bottom: 20px;
display: inline-block;
width: 100%;
vertical-align: top;
}
.iframe-container.small {
width: 32%;
height: 400px;
}
.iframe-container.large {
width: 100%;
height: 800px;
}
.iframe-container iframe {
width: 100%;
height: 100%;
border: none;
overflow: hidden;
}
.image-display img {
border: 1px solid #ddd;
border-radius: 4px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
margin-bottom: 20px;
max-width: 100%;
display: block;
margin-left: auto;
margin-right: auto;
}
.select-input {
margin-bottom: 20px;
}
.visualizations {
margin-top: 30px;
}
.histology-container {
text-align: center;
margin-bottom: 30px;
}
.histology-container img {
max-width: 80%;
height: auto;
}
.marker-list {
margin-top: 20px;
font-size: 14px;
}
.marker-list pre {
background-color: #f8f9fa;
padding: 10px;
border: 1px solid #ddd;
border-radius: 4px;
max-height: 200px;
overflow-y: auto;
}
.marker-list-label {
font-weight: bold;
margin-top: 20px;
font-size: 16px;
}
"
# JavaScript code to dynamically adjust iframe height
custom_js <- "
function resizeIframes() {
var iframes = document.querySelectorAll('iframe');
iframes.forEach(function(iframe) {
iframe.onload = function() {
var iframeDocument = iframe.contentDocument || iframe.contentWindow.document;
iframe.style.height = iframeDocument.body.scrollHeight + 'px';
};
});
}
document.addEventListener('DOMContentLoaded', resizeIframes);
Shiny.addCustomMessageHandler('resizeIframes', resizeIframes);
"
ui <- fluidPage(
theme = shinytheme("cerulean"),
tags$head(tags$style(HTML(custom_css))),
tags$head(tags$script(HTML(custom_js))),
titlePanel("Spatial Transcriptomics Visualizations"),
sidebarLayout(
sidebarPanel(
class = "sidebar",
tags$h3("Select Options:"),
div(class = "select-input",
selectInput("sample", "Select Sample:",
choices = c("DSG_67289", "DSG_67291", "DSG_67292", "DSG_67293",
"DSG_67294", "DSG_67295", "DSG_67296", "DSG_67297",
"DSG_67298", "DSG_67300", "DSG_67804", "DSG_67805"))),
div(class = "select-input",
selectInput("cellType", "Select Cell Type:",
choices = c("All" = "All", cell_types_named), selected = "All")),
uiOutput("markerListDisplay")
),
mainPanel(
class = "main-panel",
uiOutput("tissueTypeDisplay"),
div(class = "histology-container", uiOutput("imageDisplay")),
tags$h4("Visualizations"),
div(class = "visualizations", uiOutput("pdfDisplay"))
)
)
)
server <- function(input, output, session) {
output$tissueTypeDisplay <- renderUI({
req(input$sample) # Ensure input is not empty
sample_row <- samples_info[samples_info$`Template ID` == input$sample, ]
if (nrow(sample_row) > 0 && !is.na(sample_row$`Tissue type`)) {
tissueType <- sample_row$`Tissue type`
tags$h5(tissueType, class = "tissue-description")
} else {
tags$h5("No tissue type description found.", class = "no-description")
}
})
output$imageDisplay <- renderUI({
req(input$sample)
imagePath <- normalizePath(file.path("/Users/cameronwalker/Documents/BCM/Shiny/tissue_images", input$sample, "tissue_hires_image.png"), mustWork = FALSE)
if (file.exists(imagePath)) {
tags$img(src = sub("^/Users/cameronwalker/Documents/BCM/Shiny", "http://localhost:8000", imagePath))
} else {
h5("No histology image found.", class = "no-description")
}
})
output$pdfDisplay <- renderUI({
req(input$sample)
sampleDir <- file.path("/Users/cameronwalker/Documents/BCM/Shiny/DSG", input$sample)
pdfFiles <- list.files(path = sampleDir, pattern = "\\.pdf$", full.names = TRUE)
if (input$cellType != "All") {
cellTypePattern <- paste0("^", gsub(" ", "_", input$cellType), "_rank_sums\\.pdf$")
pdfFiles <- pdfFiles[grepl(cellTypePattern, basename(pdfFiles))]
}
pdfURLs <- sapply(pdfFiles, function(x) sub("^/Users/cameronwalker/Documents/BCM/Shiny", "http://localhost:8000", x))
# Determine the class for iframes based on the selected cell type
iframeClass <- if (input$cellType == "All") "iframe-container small" else "iframe-container large"
iframes <- lapply(pdfURLs, function(url) {
tags$div(class = iframeClass, tags$iframe(src = url, onload = "resizeIframes()"))
})
do.call(tagList, iframes)
})
output$markerListDisplay <- renderUI({
req(input$cellType)
if (input$cellType != "All") {
markerFile <- file.path("/Users/cameronwalker/Documents/BCM/Shiny/marker_lists", paste0(gsub(" ", "_", input$cellType), ".txt"))
if (file.exists(markerFile)) {
markerGenes <- readLines(markerFile)
tags$div(
class = "marker-list",
tags$h5("Marker Genes", class = "marker-list-label"),
tags$pre(paste(markerGenes, collapse = "\n"))
)
} else {
h5("No marker list found.", class = "no-description")
}
} else {
NULL
}
})
# Send message to resize iframes whenever the pdfDisplay is rendered
observe({
input$sample
input$cellType
session$sendCustomMessage("resizeIframes", list())
})
}
shinyApp(ui = ui, server = server)
Please let me know if you have any idea what is going on.