I have a shiny app in which I define an object based on sliders and create a data.frame
from it. This gets used to create a plot, below which I'd like to include a summary table. My issue is that the plot must be defined inside of a reactive object to update based on the sliders, but I found that when I tried to access the object to print a summary inside of a different reactive object, it wasn't found.
I'd like to not run through the same calculation code twice just to get the object into the other reactive object. My two initial ideas:
save(object, file = "...")
inside the first reactive object and then putting load(file = "...")
inside the second, but it doesn't update.plotOutput
definition, but I'm pretty sure it won't update when user inputs are changed; it will just stay with the value of the initial input
object default settings.Well, just went ahead and tried the latter idea, and it doesn't even get that far:
shinyServer(...)
and it can't generate the data because my call depends on input
and it doesn't know about input
at that point.shinyServer(...)
but before renderPlot(...)
to try and make sort of a "globally available" object for all output objects, and it scolding me for trying to do something that uses input
outside of a reactive function.Here's an example to illustrate, modified from Shiny's "Hello Shiny!" example:
ui.R
library(shiny)
# Define UI for application that plots random distributions
shinyUI(pageWithSidebar(
# Application title
headerPanel("Hello Shiny!"),
# Sidebar with a slider input for number of observations
sidebarPanel(
sliderInput("obs",
"Number of observations:",
min = 1,
max = 1000,
value = 500)
),
# Show a plot of the generated distribution
mainPanel(
plotOutput("distPlot"),
tableOutput("summary")
)
))
server.R
library(shiny)
# Define server logic required to generate and plot a random distribution
shinyServer(function(input, output) {
output$distPlot <- renderPlot({
# generate an rnorm distribution and plot it
dist <- rnorm(input$obs)
hist(dist)
})
output$summary <- renderTable({
#dist <- rnorm(input$obs)
summary <- table(data.frame(cut(dist, 10)))
})
})
If you run it as is, cut
will throw and error because it doesn't know about dist
. If you uncomment the line where we re-define dist
as is done in plotOutput
, then it will work.
This is simple code -- mine is quite a bit more involved and I'd really prefer not to run it twice just to make the same result known to another reactive output.
Suggestions?
Just to flesh out the example above based on the answer in the other question I consider mine to have duplicated, the code would look like this:
library(shiny)
# Define server logic required to generate and plot a random distribution
shinyServer(function(input, output) {
dist <- reactive(rnorm(input$obs))
output$distPlot <- renderPlot({
# generate an rnorm distribution and plot it
dist <- dist()
hist(dist)
})
output$summary <- renderTable({
dist <- dist()
summary <- table(data.frame(cut(dist, 10)))
})
})
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With