在更新几个反应依赖项后控制执行流程

Ant*_*zée 6 r shiny

这是一个简单而先进的问题.这是一个演练:

我有三个输入i_1,i_2,i_3,它们导致三个在不同功能中使用的无功值:

I1 <- reactive({input$i_1})
I2 <- reactive({input$i_2})
I3 <- reactive({input$i_3})
Run Code Online (Sandbox Code Playgroud)

具体来说,这三个值用于将图形绘制为反应性端点:

output$plot <- renderPlot {(
    plot( f(I1(), I2(), I3()) )
)}
Run Code Online (Sandbox Code Playgroud)

闪亮的魔法工作,一切正常,直到我想加载一些数据并修改三个i_X值:

observe {(
  input$b_Load #Load button
  [...]
  updateSelectInput(session,"i_1", value = 4)
  updateSelectInput(session,"i_2", value = 3)
  updateSelectInput(session,"i_3", value = 5)
  ...
)}
Run Code Online (Sandbox Code Playgroud)

更新本身工作正常,变量的三个新值将发送到客户端.

问题:然后更新这些值并逐个发送回服务器,每次不必要地重新计算图形.当所有值都更新时,我只想更新一次图表.可能吗?


我试图等待onFlushed事件:

  values <- reactiveValues(loadingProfile = FALSE)

  session$onFlushed(function() {
    values$loadingProfile <- FALSE
    cat("##### DEBUG: loading Profile OFF ##############\n", file = stderr())
  }, once = FALSE)

  output$plot <- renderPlot {(
    if (!values$loadingProfile) {
      plot( f(I1(), I2(), I3()) )
    }
  )}

  observe {(
    input$b_Load #Load button
    values$loadingProfile <- TRUE #Toggle on the watching value
    cat("##### DEBUG: loading Profile ON ##############\n", file = stderr())
    [...]
    updateSelectInput(session,"i_1", value = 4)
    updateSelectInput(session,"i_2", value = 3)
    updateSelectInput(session,"i_3", value = 5)
    ...
  )}
Run Code Online (Sandbox Code Playgroud)

但它不起作用,因为每次将三个更新版本中的一个发送回服务器时刷新会话...(我在激活跟踪后检查了控制台)


什么不能正常工作:

  • 按照@jdharrison的建议计算事件可能是一个很好的黑客,但在这里不起作用,因为如果加载的值与updateSelectInput()以前相同,则不会发回该值.
  • 等等,有点像invalidateLater(2000, session)有点作品(我试过),但不健壮.不可能指定一个总是捕获不同交换而没有超调的时间,从而暂停执行太长时间.

Ant*_*zée 2

根据我对 Shiny 当前状态的了解,这个问题本身没有答案。尽管如此,使用很棒的reactive()表达式,我已经能够重构值流并仅更新图形一次。事实上

output$plot <- renderPlot {(
  plot( f(User()) )
)}

observe {(
  input$b_Load #Load button
  updateSelectInput(session,"i_1", value = 4)
  updateSelectInput(session,"i_2", value = 3)
  updateSelectInput(session,"i_3", value = 5)
  ...
)}

User <- reactive({
  object <- list()
  object$i1 <- I1()
  object$i2 <- I2()
  object$i3 <- I3()
)}
Run Code Online (Sandbox Code Playgroud)

+ 的一个小重写f()

在这里,User()反应式表达式扮演了缓冲区的角色。它将等待所有先前的更改被推送,然后再将其自己的值发送到f()

我已在Github上分享了完整的 Shiny 项目,以获取更多信息。