I'd like to use a Shiny app to set some variables interactively. Rather than defining some objects/variables at the top of my script I'd like to launch an app and use the sliders/textInputs/radioButtons to define their values. I'd like to do this so that I can use those variables downstream, much like one might with something like
readline(prompt = "Choose a value for your variable: ")
The minimal Shiny app I can imagine for this use case is something like the below:
library(shiny)
ui <- fluidPage(
h3("Set the value for downstream analysis!"),
sliderInput(inputId = "value", label="Value", min = 0, max = 10, value = 1),
actionButton(inputId = "endsession", label = "Send to R")
)
server <- function(input, output){
observeEvent(input$endsession, {
# value_from_shiny <<- input$value
assign("value_from_shiny", input$value, envir = .GlobalEnv)
stopApp()
})
}
shinyApp(ui, server)
which correctly launches the app, accepts input interactively, and leaves that input accessible downstream. However, this solution (and most others I've found) use the <<-
or assign(envir = .GlobalEnv)
options which can be problematic due to the assignment of global variables. Alternatively, I've considered are writing this out to a temporary file that's then read in and deleted which still feels problematic. I could also use external environments but those feel like they have the same problem as the global environment as far as side effects go but are maybe the best option:
external_env <- environment()
...
assign("value_from_shiny", input$value, envir = external_env)
...
external_env$value_from_shiny
Is there a simpler way to return a value from a Shiny app? Or is that just not what they're meant to do and the <<-
method is the best I'll get? I am hoping to build this kind of interactivity into a package where this method is used to interactively classify a dataset so I'd like it to be reasonably robust and at least passing CRAN checks. My dream use case is something where the output from the app can be returned like a normal variable and accessed:
value_from_shiny <- shinyApp(ui, server)
but I also realize this is not at all how shinyApp works.
You can put the value you want to return in stopApp
, and use runApp
to get it.
library(shiny)
ui <- fluidPage(
h3("Set the value for downstream analysis!"),
sliderInput(inputId = "value", label="Value", min = 0, max = 10, value = 1),
actionButton(inputId = "endsession", label = "Send to R")
)
server <- function(input, output){
observeEvent(input$endsession, {
stopApp(input$value)
})
}
runApp(shinyApp(ui, server))