Arguments to runApp and friends #440

Closed
aecay opened this Issue Apr 16, 2014 · 4 comments

Comments

Projects
None yet
5 participants
@aecay

aecay commented Apr 16, 2014

I've built a Shiny app which takes a data frame of measurement sites (map coordinates and features measured there) and allows the user to draw various kinds of maps. The usecase for this app is not a large-scale server deployment, but rather as a tool for individual researchers to download and use to explore various combinations of settings for a (fairly complex) data simplification and plotting procedure.

Currently, the app reads .GlobalEnv to offer the user a dropdown list to select the data frame of interest from all the data frames in his/her R session. However, the case of a user switching between datasets is rare. What I'd most like is to allow the user to specify their dataset as an argument to the runApp function (or runGitHub, runGist, ...):

runApp("explore-maps", dataset = my.data)

Then any extra args passed to runApp would be accessible as a list in the server function:

shinyServer(function (input, output, session, args) {
    dataset <- args[["dataset"]]
    ...
})

Is this a possible feature addition? (Or is there some obvious way to do this using existing features that I've missed?)

@jcheng5

This comment has been minimized.

Show comment
Hide comment
@jcheng5

jcheng5 Apr 16, 2014

Member

There are currently two ways to do this.

  1. Sorta gross--make your own function to wrap runApp (which is probably a good idea anyway) that sets the desired dataset as a global variable with a well known name.
exploreSettings <- function(dataset, ...) {
  .GlobalEnv$.aecay.dataset <- dataset
  on.exit(rm(.aecay.dataset, envir=.GlobalEnv))
  runApp(appdir, ...)
}

In your server.R you would reference .aecay.dataset.

  1. Rather than write your app using ui.R and server.R, you can write your app using an object. It's hard to explain, so here's an example: https://github.com/jcheng5/seattle-meetup/blob/master/diamonds2/explore.R
Member

jcheng5 commented Apr 16, 2014

There are currently two ways to do this.

  1. Sorta gross--make your own function to wrap runApp (which is probably a good idea anyway) that sets the desired dataset as a global variable with a well known name.
exploreSettings <- function(dataset, ...) {
  .GlobalEnv$.aecay.dataset <- dataset
  on.exit(rm(.aecay.dataset, envir=.GlobalEnv))
  runApp(appdir, ...)
}

In your server.R you would reference .aecay.dataset.

  1. Rather than write your app using ui.R and server.R, you can write your app using an object. It's hard to explain, so here's an example: https://github.com/jcheng5/seattle-meetup/blob/master/diamonds2/explore.R
@jcheng5

This comment has been minimized.

Show comment
Hide comment
@jcheng5

jcheng5 Apr 16, 2014

Member

BTW it might be a good idea to distribute your Shiny app as a package. http://shiny.rstudio.com/articles/deployment-local.html#package

Member

jcheng5 commented Apr 16, 2014

BTW it might be a good idea to distribute your Shiny app as a package. http://shiny.rstudio.com/articles/deployment-local.html#package

@jcheng5 jcheng5 closed this Apr 16, 2014

@yihui yihui added this to the 0.10.0 milestone Apr 18, 2014

@daattali

This comment has been minimized.

Show comment
Hide comment
@daattali

daattali Feb 18, 2018

Contributor

@jcheng5 I was just experimenting out of curiousity and found this thread. This issue was created long before gadgets existed, which would be another option but involve some refactoring. Just wondering - is your second solution (using an app object) possible to do when there is also a global.R file, without having to manually source the global.R file?

Contributor

daattali commented Feb 18, 2018

@jcheng5 I was just experimenting out of curiousity and found this thread. This issue was created long before gadgets existed, which would be another option but involve some refactoring. Just wondering - is your second solution (using an app object) possible to do when there is also a global.R file, without having to manually source the global.R file?

@oganm

This comment has been minimized.

Show comment
Hide comment
@oganm

oganm Feb 27, 2018

It seems like the only "good" solution is using an app object, however that is problematic in terms of organisation if the app is large.

Something like the .GlobalEnv$.aecay.dataset solution works fine but I am scared that it might overwrite a user variable. Maybe something like

globalObjects = ls(.GlobalEnv)
if(".aecay.dataset" %in%  globalObjects){
    oldDataset = .GlobalEnv$.aecay.dataset
}
 .GlobalEnv$.aecay.dataset = dataset

on.exit({
    if(exists(oldDataset){
          .GlobalEnv$.aecay.dataset = oldDataset
    } else{
        rm(.aecay.dataset, envir=.GlobalEnv)
    }
})

would work reliably but it seems to wordy for something like this.

oganm commented Feb 27, 2018

It seems like the only "good" solution is using an app object, however that is problematic in terms of organisation if the app is large.

Something like the .GlobalEnv$.aecay.dataset solution works fine but I am scared that it might overwrite a user variable. Maybe something like

globalObjects = ls(.GlobalEnv)
if(".aecay.dataset" %in%  globalObjects){
    oldDataset = .GlobalEnv$.aecay.dataset
}
 .GlobalEnv$.aecay.dataset = dataset

on.exit({
    if(exists(oldDataset){
          .GlobalEnv$.aecay.dataset = oldDataset
    } else{
        rm(.aecay.dataset, envir=.GlobalEnv)
    }
})

would work reliably but it seems to wordy for something like this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment