Могу ли я сохранить старое значение реактивного объекта при его изменении?

Примечание: после придумывания ответа я переформулировал вопрос, чтобы сделать его более ясным.

иногда shiny app. Я хочу использовать значение, выбранное пользователем для виджета, а также Предыдущее значение, выбранное для того же виджета. Это может применяться к реактивным значениям, полученным из пользовательского ввода, где я хочу старое и новое значение.

проблема в том, что если я попытаюсь сохранить значение виджета, то переменная, содержащая это значение должно быть реактивным, иначе оно не будет обновляться при каждом изменении виджета. Но если я сохраню значение в реактивном контексте, оно всегда даст мне текущее значение, а не Предыдущее.

как я могу сохранить Предыдущее значение виджета, но по-прежнему обновлять его каждый раз, когда пользователь изменяет виджет?

есть ли способ, который не требует использования actionButton каждый раз, когда пользователь меняет? Избегая actionButton может быть желательно с добавлением одного в противном случае ненужный и создает избыточный щелчок для пользователя.

2 ответов


видя, что метод события сеанса flush, похоже, сломан для этой цели, вот альтернативный способ сделать это с помощью observeEvent построить и реактивную переменную.

library(shiny)

ui <- fluidPage(
  h1("Memory"),
  sidebarLayout(
    sidebarPanel(
      numericInput("val", "Next Value", 10)
    ),
    mainPanel(
      verbatimTextOutput("curval"),
      verbatimTextOutput("lstval")
    )
  )
)

server <- function(input,output,session) {
  rv <- reactiveValues(lstval=0,curval=0)

  observeEvent(input$val, {rv$lstval <- rv$curval; rv$curval <- input$val})

  curre <- reactive({req(input$val);  input$val; rv$curval})
  lstre <- reactive({req(input$val);  input$val; rv$lstval})

  output$curval <- renderPrint({sprintf("cur:%d",curre())})
  output$lstval <- renderPrint({sprintf("lst:%d",lstre())})
}
options(shiny.reactlog = TRUE)
shinyApp(ui, server)

урожайность:

enter image description here


обновление этот ответ был опубликован до появления reactiveValues/observeEvent модель shiny. Я думаю, что ответ @MikeWise-лучший способ сделать это.

после некоторых игры вокруг это то, что я придумал. Пользовательский интерфейс.r ничего особенного

ui.r

library(shiny)

ui <- shinyUI(fluidPage(
  sidebarLayout(
    sidebarPanel(
      selectizeInput(inputId="XX", label="Choose a letter",choices=letters[1:5])
    ),
    mainPanel(
      textOutput("Current"),
      textOutput("old")
    )
  ) 
))  

"Current" отобразит текущий выбор и "old" отображает предыдущий выбор.

на server.r Я из трех ключевых функций:reactiveValues, isolate и session$onFlush.

сервер.r

library(shiny)

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

  Values<-reactiveValues(old="Start")

  session$onFlush(once=FALSE, function(){
    isolate({ Values$old<-input$XX })
  })


  output$Current <- renderText({paste("Current:",input$XX)})

  output$old <- renderText({ paste("Old:",Values$old) })
}  

на server.r как это работает.

во-первых,Values$old создается с помощью