Search code examples
rshinymontecarlo

How to Store Monte Carlo Simulation Outputs Within a reactive() Function In Shiny


I have been working on a side project that involves a simple shiny app that allows users to input the parameters of a dice roll for a board game then have the code preform 10,000 rolls with those parameters and present the average of the rolls. I have a basic code that successfully makes this happen but I am struggling how to make it into a shiny app to make accessible to others.

The issue I face is that in the server part of the shiny code I do not know how to store the intermediate results within a single reactive() function. Is there a local storage option that works with a repeating function?

The code I am using is:

# Define UI for application that draws a histogram
ui <- fluidPage(

   # Application title
   titlePanel("10,000 Roll Simulator"),

   # Sidebar with a slider input for number of bins 
   sidebarLayout(
      sidebarPanel(
         numericInput(inputId = "num_tac", label = "TAC", 
                      value =1 , min = 1, max = 20),
         numericInput(inputId = "num_def", label = "DEF", 
                      value =1 , min = 1, max = 10),
         numericInput(inputId = "num_arm", label = "ARM", 
                      value =0 , min = 0, max = 10)
      )
   )
)

server <- function(input, output){
 data()<- reactive({
   One_roll<- function(){dice <- sample(1:6, size = input$num_tac, replace = TRUE)
   return(sum((dice >= input$num_def)-input$num_arm))
   sims<-replicate(10000, One_roll()}
output$stats <- renderPrint({mean(data())})
}
# Run the application 
shinyApp(ui = ui, server = server)

Any help would be greatly appreciated, thank you!


Solution

  • A few issues with your code :

    • data()<- is not allowed. Use data<- instead then call it with data()

    • Using input$ inside a function is definitely not the right way to pass parameters

    This is a modified server function where the One_roll function is defined outside the reactive, but called inside, with input passed as parameters:

    server <- function(input, output){
      One_roll<- function(num_tac,num_def,num_arm){
        dice <- sample(1:6, size = num_tac, replace = TRUE)
        sum((dice >= num_def)-num_arm)
      }
      data<- reactive(replicate(10000, One_roll(input$num_tac,input$num_def, input$num_arm )))
      output$stats <- renderPrint(mean(data()))
    }
    

    And also you need a textOutput in the ui function to call the renderText for example:

    ui <- fluidPage(
    
      # Application title
      titlePanel("10,000 Roll Simulator"),
    
      # Sidebar with a slider input for number of bins 
      sidebarLayout(
        sidebarPanel(
          numericInput(inputId = "num_tac", label = "TAC", 
                       value =1 , min = 1, max = 20),
          numericInput(inputId = "num_def", label = "DEF", 
                       value =1 , min = 1, max = 10),
          numericInput(inputId = "num_arm", label = "ARM", 
                       value =0 , min = 0, max = 10)
        ), mainPanel = textOutput("stats")
      )
    )