pyll
pyll

Reputation: 1754

Reactive Loop in R Shiny

I've been stuck on this problem for hours. I tried to create a simpler version of my actual use case to see if I can debug the problem but still having trouble.

My shiny app is below. It takes an input from user, runs it through some calculations until it meets a threshold, then collects the value in a list. It does this for several iterations (10 here in the example), then plots a histogram of these values.

The specific error I'm getting says

Warning: Error in : evaluation nested too deeply: infinite recursion / options(expressions=)?

I think that my error is related to the way I'm using x.new, but I can't figure out how to code it differently.

# install.packages('shiny')
library(shiny)
ui <- fluidPage(
  headerPanel('Title Here'),
  sidebarPanel(
    numericInput('x.qty', 'Pick a number', 3, 1, 10)),
  mainPanel(plotOutput('valueplot'))
)

server <- function(input, output, session) {
  results <- reactive({
    x.list <- list()
    for (i in 1:10){
      x.new <- reactive({input$x.qty * sample(1:10, 1)})
      repeat{
        if (x.new() > 20){
          x.list <- c(x.list, x.new())
          results <- x.list
          break
        } # end if loop
        x.new <- reactive({x.new() * sample(1:10, 1)})
      } # end repeat
    } # end for loop
    results
  })
  output$valueplot <- renderPlot({hist(as.numeric(results()))})
}  

shinyApp(ui = ui, server = server)

Upvotes: 0

Views: 1675

Answers (2)

ge.org
ge.org

Reputation: 69

I would suggest to modify your server function in the following way:

server <- function(input, output, session) {
  results <- reactive({
    x.list <- list()
    for (i in 1:10){
      x.new <- input$x.qty * sample(1:10, 1)
      repeat{
        if (x.new > 20){
          x.list <- c(x.list, x.new)
          results <- x.list
          break
        } # end if loop
        x.new <- x.new * sample(1:10, 1)
      } # end repeat
    } # end for loop
    results
  })
  output$valueplot <- renderPlot({hist(as.numeric(results()))})
}  

This way you avoid the infinite recursion provoked by

x.new <- reactive({x.new() * sample(1:10, 1)})

Upvotes: 1

rdh
rdh

Reputation: 1045

Does this work as you want? Each for loop iteration, x.new is calculated using x.qty then in the repeat loop x.new recursively multiplies itself by a random number until it is greater than 20.

library(shiny)

ui <- fluidPage(headerPanel('Title Here'),
                sidebarPanel(numericInput('x.qty', 'Pick a number', 3, 1, 10)),
                mainPanel(plotOutput('valueplot')))

server <- function(input, output, session) {

  x.new <- function(x) {
    x * sample(1:10, 1)
  }

  results <- reactive({
    x.list <- list()
    for (i in 1:10) {
      x.new_draw <- x.new(input$x.qty)
      repeat {
        if (x.new_draw > 20) {
          x.list <- c(x.list, x.new_draw)
          break
        } # end if loop
        x.new_draw <- x.new(x.new_draw)
      } # end repeat
    } # end for loop
    x.list
  })
  output$valueplot <- renderPlot({
    hist(as.numeric(results()))
  })

}

shinyApp(ui = ui, server = server)

Upvotes: 1

Related Questions