Chapter 6 Troubleshooting

6.1 Package installation

Most packages are installed from CRAN using install.packages or bioconductor using BiocManager::install(). Make sure to also install dependencies, and check to see which functions are masked by other packages if you change the order of loading libraries.

Some require installation from github, using devtools. For example, dict installation:

if (!require("devtools")) install.packages("devtools")
devtools::install_github("mkuhn/dict")

If you are using Windows and struggling with compilation, make sure RTools is installed properly (https://cran.r-project.org/bin/windows/Rtools/rtools42/rtools.html). If you don’t have write permissions to update packages, this may require administrator access.

6.2 File setup

The most common error is that your file names or PATH is incorrect.

6.3 Styling

If you are using a style sheet (style.css), first make sure it’s in the correct repository. Are default options from Shiny overriding the options in your style sheet? Check options for each function. For more help, see https://shiny.rstudio.com/articles/css.html.

# example fluidRow
tabItem(tabName = tabName,
        fluidRow(box(title = datasetTitle,
                     status = "primary", # these with affect styling
                     solidHeader = TRUE, # these with affect styling
                     if (is.null(des_dir) == FALSE) {includeHTML(des_dir)},
                     if (is.null(image_dir) == FALSE) {img(src = image_dir, height = 150, width = 400)}
        )),br(),
        actionLink(NS(id, "link_to_home"), "Home", icon = icon("home")),br(),br(),
        actionButton(NS(id, "load"), "Plot Graphs")
)

6.4 Data input/output issues

Ensure that the data you are inputting into the app is in the correct format, and that the output is being generated correctly. Check if there are any issues with the data or if there are errors in the code that is manipulating the data. You can print data at each step of pre-processing to evaluate their format.

An example is the step of calculating median expression from all samples and grouping them based on experimental parameters. Use print() function throughout to monitor mistakes.

# load count data and colData 
count   = read.csv("./data/CountTables/TPM_mouse.csv", header = TRUE)
count$gene = count$X
## print(count)

colData = read.csv(paste0("./data/colData/", "TPM_mouse_colData.csv"), header = TRUE)
rownames(colData) = colData[,1]
## print(colData)

# filter rows of genes queried 
df = count[count$symbol %in% c("Gnai3", "Scml12"),]
## print(df)

# remove the symbol column 
df$gene = df$X
filt = df[,!names(df) %in% c("symbol","X")]
rownames(filt) = filt$gene
## print(filt)

# convert wide to long data frame based on the rownames of colData and rownames of count data 
# this requires rownames(tcounts) to be gene IDs and rownames(colData) to be the same as colnames(tcounts)
# mistakes are generated if those columns do not match. 
tcounts <- t(filt) %>%
  base::merge(colData, ., by="row.names") %>%
  gather(gene, expression, (ncol(.)-nrow(filt)+1):(ncol(.)))
## print(tcounts)

# add back symbols
tcounts$symbol = count[count$X %in% tcounts$gene,]$symbol
## print(tcounts)

# display datasets 
kbl(tcounts %>% head) %>% kable_styling(bootstrap_options = c("striped", "hover", "condensed", "responsive"), font_size = 12, latex_options = "scale_down") %>% scroll_box(width = "100%", height = "200px")
Row.names X Sample Population Condition Sex Sample_Pop_Cond_Sex Dataset Species Timepoint gene expression symbol
Sample49_BALB.c_SNI_M Sample49_BALB.c_SNI_M Sample49 BALB.c SNI M Sample49_BALB.c_SNI_M Bulk DRG Mouse (DRG) na ENSMUSG00000000001 23.24143 Gnai3
Sample50_BALB.c_SHAM_M Sample50_BALB.c_SHAM_M Sample50 BALB.c SHAM M Sample50_BALB.c_SHAM_M Bulk DRG Mouse (DRG) na ENSMUSG00000000001 20.64601 Gnai3
Sample51_BALB.c_SHAM_M Sample51_BALB.c_SHAM_M Sample51 BALB.c SHAM M Sample51_BALB.c_SHAM_M Bulk DRG Mouse (DRG) na ENSMUSG00000000001 20.96847 Gnai3
Sample55_BALB.c_SHAM_F Sample55_BALB.c_SHAM_F Sample55 BALB.c SHAM F Sample55_BALB.c_SHAM_F Bulk DRG Mouse (DRG) na ENSMUSG00000000001 25.60511 Gnai3
Sample56_BALB.c_SHAM_F Sample56_BALB.c_SHAM_F Sample56 BALB.c SHAM F Sample56_BALB.c_SHAM_F Bulk DRG Mouse (DRG) na ENSMUSG00000000001 17.92455 Gnai3
Sample57_BALB.c_SHAM_F Sample57_BALB.c_SHAM_F Sample57 BALB.c SHAM F Sample57_BALB.c_SHAM_F Bulk DRG Mouse (DRG) na ENSMUSG00000000001 21.82794 Gnai3

6.5 Debugging reactive code

Reavtive components respond to user inputs. This allows users to interact with the data in real-time, updating visualizations and other content as they change settings or filters. Reactive components can be created using the reactive() function in Shiny. An example is shown below:

For example,

library(shiny)

# Define the UI
ui <- fluidPage(
  # Input field for a number
  numericInput(inputId = "my_number", label = "Enter a number:", value = 1),
  # Text output for the number squared
  textOutput(outputId = "my_output")
)

# Define the server
server <- function(input, output) {
  # Define a reactive expression for the square of the number
  squared <- reactive({
    input$my_number^2
  })
  
  # Output the squared number to the text output
  output$my_output <- renderText({
    paste0("The square of ", input$my_number, " is ", squared())
  })
}

# Run the app
shinyApp(ui, server)

The example above uses the numericInput() function to create an input field where the user can enter a number. We then use the reactive() function to define a reactive expression called squared, which calculates the square of the input number. Finally, we use the renderText() function to display the squared number in a text output component.

Note that the squared reactive expression is not evaluated until it is actually used in the renderText() function. This means that it will only be re-evaluated when the input value my_number changes.

To debug reactive code, there are a few tips.

  1. Use the print() function to print out intermediate results of the reactive code to see where the problem is arising. For example, you can print the value of a reactive input or output to see if it is being calculated correctly. You can also use the reactiveValues() function to create reactive values that can be printed out for debugging purposes.
# Example of using print statements to debug reactive code
output$my_output <- renderText({
  x <- input$my_input
  print(x) # Print the value of x for debugging purposes
  x * 2 # Return the value of x times 2
})
  1. Use the browser() function to pause the execution of the code at a particular point, which will allow you to inspect the current environment. This can be particularly useful for debugging complex reactive code. To use the browser() function, simply add it to the reactive expression where you want to pause the code.
# Example of using the browser function to debug reactive code
output$my_output <- renderText({
  x <- input$my_input
  browser() # Pause execution and allow user to inspect environment
  x * 2 # Return the value of x times 2
})

When the app runs and the server function is called, it will pause at the browser() statement. In the R console or IDE, you can then examine the value of the input variable by typing input at the prompt, or check the current state of the app by typing other R commands.

Once you are finished debugging, you can continue the app execution by typing c (for “continue”) in the R console. The app will resume execution and the output will be displayed in the Shiny app UI.

  1. Check for dependencies: Reactive expressions can sometimes depend on other reactive expressions or reactive values, and it can be challenging to trace the dependencies. The reactiveLog() function in the reactlog package can be useful for visualizing the dependencies between reactive expressions.
library(shiny)
library(shinydebug)

ui <- fluidPage(
  textInput("name", "Enter your name:"),
  verbatimTextOutput("greeting")
)

server <- function(input, output) {
  # Use reactiveLog() to log the execution of the reactive expression
  reactiveLog({
    name <- input$name
    paste0("Hello, ", name, "!")
  }, label = "greeting")
  
  # Render the greeting text in the output
  output$greeting <- renderText({
    reactiveValuesToList(reactiveLogData()$greeting$value)[[1]]
  })
}

shinyApp(ui, server)

In this example, we’re using reactiveLog() to log the execution of a reactive expression that generates a greeting message based on the user’s input. We’re also using the label argument to assign a label to the reactive expression, which will be used to identify it in the log.

When the app runs, the reactiveLog() function will log the execution of the reactive expression and display it in the R console or IDE, along with a timestamp and the label. You can use the log to observe the order in which reactive expressions are executed and identify any issues or unexpected behavior.

In the output$greeting function, we’re using reactiveLogData() to retrieve the log data for the “greeting” label, and then extracting the value of the reactive expression using reactiveValuesToList(). This allows us to render the greeting text in the app output.

  1. Use tryCatch(): If your reactive code is throwing errors, you can use the tryCatch() function to catch the errors and display a custom error message. This can be useful for debugging errors that occur during reactive code execution.
# Example of using the tryCatch function to catch errors in reactive code
output$my_output <- renderText({
  tryCatch({
    x <- input$my_input
    x * 2 # Return the value of x times 2
  }, error = function(e) {
    "An error occurred while calculating the output." # Display a custom error message
  })
})

6.6 Deployment

Simple apps can be directly deployed with rsconnect::deployApp(), but it is common to have issues with the first deployment even when the app works locally. Here are a few examples below, but your error code will help inform a starting point (in particular, is there one package highlighted as a potential issue?)

6.6.1 Basics

  1. Slow deployment: Uploading bundle for application and building packages will take time. Are you loading unneccessary data or packages?
  2. Memory: check Instance Size on shinyapps.io, this can be increased with specific pricing packages.

6.6.2 Bioconductor

Because this framework uses Biocondutor packages, it is likely you need to set the repository (URL).

# example error 1: you need to set a URL

May be unable to deploy package dependency 'AnnotationDbi'; could not
determine a repository URL for the source 'Bioconductor'.

# example error 2: the URL is set but not sufficient to compile packages, may need to try another Bioconductor version, update packages, fix compiling, turn off a firewall, or update R

Unhandled Exception: Child Task 873781155 failed: Error parsing manifest: 
Unable to determine package source for Bioconductor package

# example error 3: you likely have a mismatch in versions across packages, which may be compatible locally by cause issues on shinyapp.io. Here, use BiocManager::valid() to ensure all packages are in agreement
Error: Unhandled Exception: Child Task 1278414280 failed: Error building image: Error fetching GenomeInfoDbData (1.2.9) source. Error downloading package source. Please update your BioConductor packages to the latest version and try again

Example (truncated) output from BiocManager::valid(). If you need to compile something by source to get the most recent version, make sure have installed the required packages (eg. RTools for Windows).

BiocManager::valid()
# Bioconductor version '3.16'
# 
#   * 1 packages out-of-date
#   * 0 packages too new
# 
# create a valid installation with
# 
#  BiocManager::install("sfheaders", update = TRUE, ask = FALSE, force = TRUE) ## run this part to fix
# 
# more details: BiocManager::valid()$too_new, BiocManager::valid()$out_of_date
#

You can specific the bioconductor repository here (depending on updates, a very new version may be incompatible with Shiny briefly). You can check which repositories have been set using getOption("repos").

setRepositories(addURLs = c(BioC = "https://bioconductor.org/packages/3.16/bioc")) #specify version here

# alternatively, this can be run at the top of the UI and *may* help
library(BiocManager)
options(repos = BiocManager::repositories())

If there is a specific package referred to, check the installation to make sure it was successful (see above). You can force a new install using force = TRUE, but restart R before trying again.

If you are planning to update many packages, you can check which are valid first.

BiocManager::valid() 

Still not working? A few other things to look for:

  1. Package dependency mismatch between CRAN and Bioconductor (check rsconnect::appDependencies())
  2. Make sure you are using a released version of R (shinyapps.io doesn’t support beta versions, and you may need to revert to a released version of R and update packages.)
  3. Your local firewall/antivirus may be blocking deployment.

If all else fails, try posting on the community forum for help (<https://community.rstudio.com/) and tag Shiny and shinyapp.io with a reproducible example (ie. reprex). See https://community.rstudio.com/t/faq-tips-for-writing-r-related-questions/6824 for how to best format this.

For reference, the following were used for our database.

rsconnect::appDependencies()
##              package   version       source
## 1      AnnotationDbi    1.60.2 Bioconductor
## 2            Biobase    2.58.0 Bioconductor
## 3      BiocFileCache     2.6.1 Bioconductor
## 4       BiocGenerics    0.44.0 Bioconductor
## 5         Biostrings    2.66.0 Bioconductor
## 6                DBI     1.1.3         CRAN
## 7       GenomeInfoDb    1.34.9 Bioconductor
## 8   GenomeInfoDbData     1.2.9 Bioconductor
## 9            IRanges    2.32.0 Bioconductor
## 10          KEGGREST    1.38.0 Bioconductor
## 11              MASS  7.3-58.2         CRAN
## 12            Matrix     1.5-3         CRAN
## 13                R6     2.5.1         CRAN
## 14      RColorBrewer     1.1-3         CRAN
## 15             RCurl 1.98-1.10         CRAN
## 16           RSQLite     2.3.0         CRAN
## 17              Rcpp    1.0.10         CRAN
## 18         S4Vectors    0.36.2 Bioconductor
## 19               XML 3.99-0.13         CRAN
## 20           XVector    0.38.0 Bioconductor
## 21           askpass       1.1         CRAN
## 22         base64enc     0.1-3         CRAN
## 23           biomaRt    2.54.0 Bioconductor
## 24               bit     4.0.5         CRAN
## 25             bit64     4.0.5         CRAN
## 26            bitops     1.0-7         CRAN
## 27              blob     1.2.4         CRAN
## 28          bookdown      0.33         CRAN
## 29             bslib     0.4.2         CRAN
## 30            cachem     1.0.7         CRAN
## 31             callr     3.7.3         CRAN
## 32               cli     3.6.0         CRAN
## 33        colorspace     2.1-0         CRAN
## 34             cpp11     0.4.3         CRAN
## 35            crayon     1.5.2         CRAN
## 36              curl     5.0.0         CRAN
## 37            dbplyr     2.3.2         CRAN
## 38            digest    0.6.31         CRAN
## 39             dplyr     1.1.0         CRAN
## 40          ellipsis     0.3.2         CRAN
## 41          evaluate      0.20         CRAN
## 42             fansi     1.0.4         CRAN
## 43            farver     2.1.1         CRAN
## 44           fastmap     1.1.1         CRAN
## 45          filelock     1.0.2         CRAN
## 46       fontawesome     0.5.0         CRAN
## 47                fs     1.6.1         CRAN
## 48          generics     0.1.3         CRAN
## 49           ggplot2     3.4.2         CRAN
## 50           ggrepel     0.9.3         CRAN
## 51              glue     1.6.2         CRAN
## 52         gridExtra       2.3         CRAN
## 53            gtable     0.3.3         CRAN
## 54             highr      0.10         CRAN
## 55               hms     1.1.3         CRAN
## 56         htmltools     0.5.4         CRAN
## 57              httr     1.4.5         CRAN
## 58           isoband     0.2.7         CRAN
## 59         jquerylib     0.1.4         CRAN
## 60          jsonlite     1.8.4         CRAN
## 61        kableExtra     1.3.4         CRAN
## 62             knitr      1.42         CRAN
## 63          labeling     0.4.2         CRAN
## 64           lattice   0.20-45         CRAN
## 65         lifecycle     1.0.3         CRAN
## 66          magrittr     2.0.3         CRAN
## 67           memoise     2.0.1         CRAN
## 68              mgcv    1.8-41         CRAN
## 69              mime      0.12         CRAN
## 70           munsell     0.5.0         CRAN
## 71              nlme   3.1-162         CRAN
## 72           openssl     2.0.6         CRAN
## 73           packrat     0.9.1         CRAN
## 74            pillar     1.9.0         CRAN
## 75         pkgconfig     2.0.3         CRAN
## 76             plogr     0.2.0         CRAN
## 77               png     0.1-8         CRAN
## 78       prettyunits     1.1.1         CRAN
## 79          processx     3.8.0         CRAN
## 80          progress     1.2.2         CRAN
## 81                ps     1.7.2         CRAN
## 82             purrr     1.0.1         CRAN
## 83          rappdirs     0.3.3         CRAN
## 84             rlang     1.1.0         CRAN
## 85         rmarkdown      2.21         CRAN
## 86         rsconnect    0.8.29         CRAN
## 87        rstudioapi      0.14         CRAN
## 88             rvest     1.0.3         CRAN
## 89              sass     0.4.5         CRAN
## 90            scales     1.2.1         CRAN
## 91           selectr     0.4-2         CRAN
## 92           stringi    1.7.12         CRAN
## 93           stringr     1.5.0         CRAN
## 94           svglite     2.1.1         CRAN
## 95               sys     3.4.1         CRAN
## 96       systemfonts     1.0.4         CRAN
## 97            tibble     3.1.8         CRAN
## 98             tidyr     1.3.0         CRAN
## 99        tidyselect     1.2.0         CRAN
## 100          tinytex      0.44         CRAN
## 101             utf8     1.2.3         CRAN
## 102            vctrs     0.5.2         CRAN
## 103          viridis     0.6.2         CRAN
## 104      viridisLite     0.4.1         CRAN
## 105          webshot     0.5.4         CRAN
## 106            withr     2.5.0         CRAN
## 107             xfun      0.38         CRAN
## 108             xml2     1.3.3         CRAN
## 109             yaml     2.3.7         CRAN
## 110         zlibbioc    1.44.0 Bioconductor
getOption("repos")
##                        CRAN 
## "https://cran.rstudio.com/" 
## attr(,"RStudio")
## [1] TRUE
sessionInfo()
## R version 4.2.2 (2022-10-31 ucrt)
## Platform: x86_64-w64-mingw32/x64 (64-bit)
## Running under: Windows 10 x64 (build 19042)
## 
## Matrix products: default
## 
## locale:
## [1] LC_COLLATE=English_United Kingdom.utf8  LC_CTYPE=English_United Kingdom.utf8   
## [3] LC_MONETARY=English_United Kingdom.utf8 LC_NUMERIC=C                           
## [5] LC_TIME=English_United Kingdom.utf8    
## 
## attached base packages:
## [1] stats     graphics  grDevices utils     datasets  methods   base     
## 
## other attached packages:
##  [1] viridis_0.6.2     viridisLite_0.4.1 biomaRt_2.54.0    ggrepel_0.9.3     ggplot2_3.4.2     kableExtra_1.3.4 
##  [7] stringr_1.5.0     RSQLite_2.3.0     tidyr_1.3.0       dplyr_1.1.0      
## 
## loaded via a namespace (and not attached):
##  [1] Biobase_2.58.0         httr_1.4.5             sass_0.4.5             bit64_4.0.5           
##  [5] jsonlite_1.8.4         bslib_0.4.2            BiocManager_1.30.20    highr_0.10            
##  [9] stats4_4.2.2           BiocFileCache_2.6.1    blob_1.2.4             GenomeInfoDbData_1.2.9
## [13] yaml_2.3.7             progress_1.2.2         pillar_1.9.0           glue_1.6.2            
## [17] digest_0.6.31          promises_1.2.0.1       XVector_0.38.0         rvest_1.0.3           
## [21] colorspace_2.1-0       httpuv_1.6.9           htmltools_0.5.4        XML_3.99-0.13         
## [25] pkgconfig_2.0.3        servr_0.26             bookdown_0.33          zlibbioc_1.44.0       
## [29] purrr_1.0.1            scales_1.2.1           webshot_0.5.4          svglite_2.1.1         
## [33] later_1.3.0            tibble_3.1.8           KEGGREST_1.38.0        farver_2.1.1          
## [37] generics_0.1.3         IRanges_2.32.0         cachem_1.0.7           withr_2.5.0           
## [41] BiocGenerics_0.44.0    cli_3.6.0              mime_0.12              magrittr_2.0.3        
## [45] crayon_1.5.2           memoise_2.0.1          evaluate_0.20          fansi_1.0.4           
## [49] xml2_1.3.3             rsconnect_0.8.29       tools_4.2.2            prettyunits_1.1.1     
## [53] hms_1.1.3              lifecycle_1.0.3        S4Vectors_0.36.2       munsell_0.5.0         
## [57] packrat_0.9.1          AnnotationDbi_1.60.2   Biostrings_2.66.0      compiler_4.2.2        
## [61] jquerylib_0.1.4        GenomeInfoDb_1.34.9    systemfonts_1.0.4      rlang_1.1.0           
## [65] grid_4.2.2             RCurl_1.98-1.10        rstudioapi_0.14        rappdirs_0.3.3        
## [69] labeling_0.4.2         bitops_1.0-7           rmarkdown_2.21         gtable_0.3.3          
## [73] DBI_1.1.3              curl_5.0.0             R6_2.5.1               gridExtra_2.3         
## [77] knitr_1.42             fastmap_1.1.1          bit_4.0.5              utf8_1.2.3            
## [81] filelock_1.0.2         stringi_1.7.12         Rcpp_1.0.10            vctrs_0.5.2           
## [85] png_0.1-8              dbplyr_2.3.2           tidyselect_1.2.0       xfun_0.38

Happy building!