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")
::install_github("mkuhn/dict") devtools
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.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
= read.csv("./data/CountTables/TPM_mouse.csv", header = TRUE)
count $gene = count$X
count## print(count)
= read.csv(paste0("./data/colData/", "TPM_mouse_colData.csv"), header = TRUE)
colData rownames(colData) = colData[,1]
## print(colData)
# filter rows of genes queried
= count[count$symbol %in% c("Gnai3", "Scml12"),]
df ## print(df)
# remove the symbol column
$gene = df$X
df= df[,!names(df) %in% c("symbol","X")]
filt 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.
<- t(filt) %>%
tcounts ::merge(colData, ., by="row.names") %>%
basegather(gene, expression, (ncol(.)-nrow(filt)+1):(ncol(.)))
## print(tcounts)
# add back symbols
$symbol = count[count$X %in% tcounts$gene,]$symbol
tcounts## 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
<- fluidPage(
ui # 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
<- function(input, output) {
server # Define a reactive expression for the square of the number
<- reactive({
squared $my_number^2
input
})
# Output the squared number to the text output
$my_output <- renderText({
outputpaste0("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.
- 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 thereactiveValues()
function to create reactive values that can be printed out for debugging purposes.
# Example of using print statements to debug reactive code
$my_output <- renderText({
output<- input$my_input
x print(x) # Print the value of x for debugging purposes
* 2 # Return the value of x times 2
x })
- 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 thebrowser()
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
$my_output <- renderText({
output<- input$my_input
x browser() # Pause execution and allow user to inspect environment
* 2 # Return the value of x times 2
x })
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.
- 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 thereactlog
package can be useful for visualizing the dependencies between reactive expressions.
library(shiny)
library(shinydebug)
<- fluidPage(
ui textInput("name", "Enter your name:"),
verbatimTextOutput("greeting")
)
<- function(input, output) {
server # Use reactiveLog() to log the execution of the reactive expression
reactiveLog({
<- input$name
name paste0("Hello, ", name, "!")
label = "greeting")
},
# Render the greeting text in the output
$greeting <- renderText({
outputreactiveValuesToList(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.
- Use
tryCatch()
: If your reactive code is throwing errors, you can use thetryCatch()
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
$my_output <- renderText({
outputtryCatch({
<- input$my_input
x * 2 # Return the value of x times 2
x 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
- Slow deployment: Uploading bundle for application and building packages will take time. Are you loading unneccessary data or packages?
- 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
'AnnotationDbi'; could not
May be unable to deploy package dependency for the source 'Bioconductor'.
determine a repository URL
# 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
: Child Task 873781155 failed: Error parsing manifest:
Unhandled Exceptionfor Bioconductor package
Unable to determine package source
# 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
: 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 Error
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).
::valid()
BiocManager# 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.
::valid() BiocManager
Still not working? A few other things to look for:
- Package dependency mismatch between CRAN and Bioconductor (check
rsconnect::appDependencies()
) - 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.)
- 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.
::appDependencies() rsconnect
## 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!