Reputation: 65
I am building an R package that has a function to launch a shiny app. I would like that function to include an argument to be passed to the app. The only way I found to work is setting a global value, and then having the app use that global value:
launch_app <- function(MonteCarlo=1000){
MonteCarlo_global <<- MonteCarlo
shiny::runApp(appDir = system.file("app.R", package="my_package"))
}
Is there a better way to pass my "MonteCarlo" argument to be used throughout the shiny app? Please note I'm trying to avoid simply including "MonteCarlo" as one of the input options within the app itself. I'd rather have the user not worry about it. But, if desired the knowledgeable user can control it when launching the app.
Upvotes: 5
Views: 1860
Reputation: 7695
I currently use shinyOptions
and getShinyOption
to pass arguments to shiny apps.
Also, I source
the output from shinyApp
directly rather than unsing runApp
like so
## file: R/launch_app.R
launch_app <- function(MonteCarlo = 1000){
shinyOptions(MonteCarlo = MonteCarlo)
source(system.file("app.R", package = "my_pkg", local = TRUE, chdir = TRUE))$value
}
The file app.R
can look similar to this
## file: inst/app.R
appDir <- getwd()
monte.carlo.default <- 1000
MonteCarlo <- getShinyOption("MonteCarlo", monte.carlo.default)
shinyApp(
ui = fluidPage(paste("Chosen parameter:", MonteCarlo)),
server = function(input, output, session){
oldwd <- setwd(appDir)
on.exit(setwd(oldwd))
## put more server logic here
}
)
The setwd()
part is only relevant if you are using local paths inside your server
.
Here you can also find the opinion of the creator of shiny
, Joe Cheng, about this topic.
You are right, the "standard" way is to use runApp
, but there are two reasons I chose not to do that:
First, runApp
will save all server
variables in the global environment. This means that after the app has been stopped, the users of your package will have variables in their workspace that they don't need. If you use the the design I outlined, your user's environments will not be affected by running the app.
Second, by writing your launch_app
function like this you can easily deploy apps via shiny-server
like so
## file: /srv/shiny-server/my-pkg/app.R
my_pkg::lauch_app(MonteCarlo = 800)
whch is not possible if launch_app
invokes runApp
. With the runApp
approach you need to use a symbolic link to the app folder instead which will lead to more maintenance work (for example, if .libPaths
or the structure of inst/
changes). Also, you won't be able to pass parameters to the shiny-server
version of your app as easily
Upvotes: 8