-->

Error when trying to deploy to shinyapps.io: Appli

2019-01-26 16:29发布

问题:

My server.R contains the following code for dynamically installing packages when needed:

package <- input$chip
if (!require(package, character.only=T, quietly=T)) {
      source("https://bioconductor.org/biocLite.R")
      biocLite(package, ask = F, suppressUpdates = T, suppressAutoUpdate = T)
      library(package, character.only=T)
    }

ui.R has a select input element where the user can select one of the following bioconductor packages:

selectInput(inputId = 'chip', label='Chip', choices=c('Mouse Gene 1.0'='mogene10sttranscriptcluster.db',
                                                      'Mouse Gene 2.0'='mogene20sttranscriptcluster.db',
                                                      'Human Gene 1.0'='hugene10sttranscriptcluster.db',
                                                      'Human Genome U133A 2.0'='hgu133a2.db'))

So, based on what chip the user selects, the corresponding annotation package should get loaded, and if it is not already installed, it should install it.

This works on my local machine. But when I try to deploy my app on shinyapps.io. I get the following error:

Error: 
* Application depends on package "package" but it is not installed. Please resolve before continuing.

I know that it is unable to recognize the package in biocLite(package, ask = F, suppressUpdates = T, suppressAutoUpdate = T). The deployment process thinks that package is a library name and not a variable and is unable to evaluate its value.

Is there any way to resolve this? Or do I have to explicitly load all required packages? The problem with explicitly loading the annotation packages is that these packages are so big they take up a lot of memory, which is why I wanted to load these packages only when required.

An alternative is to make an if-else loop or switch statement to install packages based on the condition:

package <- function(input$chip) {
  switch(input$chip,
         'mogene10sttranscriptcluster.db' = 'mogene10sttranscriptcluster.db',
         'mogene20sttranscriptcluster.db' = 'mogene20sttranscriptcluster.db',
         'hugene10sttranscriptcluster.db' = 'hugene10sttranscriptcluster.db',
         'hgu133a2.db' = 'hgu133a2.db')
}
library(package)

But even in this case, the deployment process won't be able to evaluate the package value.

Thanks!

UPDATE: Taking Yihui's suggestion, I modified my code to:

package <- input$genome

if(!do.call(require, list(package = package, character.only = T, quietly = T))){
  do.call(biocLite, list(pkgs = package, ask = F, suppressUpdates = T, suppressAutoUpdate = T))
  do.call(library, list(package = package, character.only = TRUE))
}

The application is able to deploy now, but it throws me this error:

Error: unable to install packages

回答1:

Unfortunately, you have to fool the shinyapps (or rsconnect) package a bit so that it does not detect package as a literal package name. For example, you may use do.call():

do.call(library, list(package = package, character.only = TRUE))

The ShinyApps.io server does not allow you to install packages on the fly (strictly speaking, this is not true, but I don't want to show you how). You have to declare all packages you need in the app as dependencies beforehand. Again, it is a hack:

if (FALSE) {
  library(mogene10sttranscriptcluster.db)
  library(mogene20sttranscriptcluster.db)
  library(hugene10sttranscriptcluster.db)
  library(hgu133a2.db)
}

Then ShinyApps.io will detect these packages as dependencies and pre-install them for you. What you need to do in your app is simply load them, and you don't need to install them by yourself.