简体   繁体   中英

Self-referencing reactive variables in Shiny (R)

I am building a shiny app that periodically reads new data, then uses that data and a previous parameter estimate to produce a new parameter estimate (and so on ad infinitum).

The issue is that the parameter must by reactive to update when the data updates, but also needs to reference its previous value, I am not sure how to use its current value to calculate its next value without shiny complaining about infinite recursion. A minimal example is below, it is intended to print a value that increments itself by 1 every second.

library(shiny)

omega <- 0

# Define the UI
myui <- basicPage(  
    textOutput('var')
)

# Define the server code
myserver <- function(input, output, session) {

    omega <<- reactive({
        invalidateLater(1000, NULL)
        return(omega() + 1)
    })

    output$var <- renderText(omega())
}


# Return a Shiny app object
shinyApp(ui = myui, server = myserver)

This produces the following error

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

If I try to protect the call to omega() within omega by using isolate() I get a segfault from a C stack overflow.

Is there a way to fix this? Or perhaps a better way to do what I want within shiny?

Here is a quick solution to the problem but does not exactly address the question.

library(shiny)

omega_nr <- 0

# Define the UI
myui <- basicPage(  
  textOutput('var')
)

# Define the server code
myserver <- function(input, output, session) {

  omega <- reactive({
    invalidateLater(1000, session)
    return(omega_nr)
  })

  # update non reactive value
  observe({
    omega()
    omega_nr<<-omega_nr+1
  })

  output$var <- renderText(omega())
}


# Return a Shiny app object
shinyApp(ui = myui, server = myserver)

This is working I just tested it.

I'll try other options and let you know. Meanwhile I'm also interested in exact solution. But somehow I feel that self referencing reactive should not be implemented. But I may be wrong..

You can just build a function that does that:

library(shiny)

myui <- basicPage(  textOutput('var'))
myserver <- shinyServer(function(input, output, session){

  omega <<- 0
  update_data <- function(){omega <<- omega + 1}

  output$var <- renderText({
    invalidateLater(1000, session)
    update_data()})
})

shinyApp(ui = myui, server = myserver)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM