gpt4 book ai didi

R Shiny - 了解更新相互依赖的输入时观察和观察事件之间的区别

转载 作者:行者123 更新时间:2023-12-04 10:31:23 25 4
gpt4 key购买 nike

下面的应用程序有两个相互依赖的数字输入,ab . input$a的值是 1-input$binput$b 的值是 1-input$a .每当用户更改输入的值时,我想相应地更新另一个的值。下面的代码包含两种方法:

  • 单个观察者
  • 两个独立的观察者——一个监听 a 的变化并更新 b,另一个监听 b和更新 a .

  • 当我尝试 1) 时,输入陷入无限循环,但我不确定我明白为什么。如果用户更改 b ,然后观察者被触发, a的值更新为 1-b .由于两个输入的值现在都是最新的, input$a 没有进一步的变化。或 input$b并且在用户进行另一次更改之前不应再次触发观察者。但事实并非如此。

    方法 1) 与方法 2) 究竟有何不同?为什么 1) 陷入循环而 2) 不会?
    library(shiny)

    shinyApp(
    ui = fluidPage(
    numericInput('a','a', value = 0.5, max = 1, min = 0),
    numericInput('b','b', value = 0.5, max = 1, min = 0)
    ),
    server = function(input, output, session) {

    # Using a single observer ----
    observe({

    updateNumericInput(session, 'a', value = 1-req(input$b))

    updateNumericInput(session, 'b', value = 1-req(input$a))

    print(input$a)

    })

    # Using separate observers ----
    # observeEvent(input$b, {
    # updateNumericInput(session, 'a', value = 1-input$b)
    # })
    #
    # observeEvent(input$a, {
    # updateNumericInput(session, 'b', value = 1-input$a)
    # })

    }
    )

    最佳答案

    observe 的文档中和 observeEvent , 这个已经写完了:

  • observe

  • An observer is like a reactive expression in that it can read reactive values and call reactive expressions, and will automatically re-execute when those dependencies change. [...] [O]bservers use eager evaluation; as soon as their dependencies change, they schedule themselves to re-execute.



    在您的示例中, observe永远不会停止“观察”并在其他更改后立即更新输入,即使用户没有做任何事情。因此,您会陷入无限循环,因为两个输入中的每一个都依赖于另一个。
  • observeEvent

  • [S]ometimes you want to wait for a specific action to be taken from the user, like clicking an actionButton(), before calculating an expression or taking an action. [...] Use observeEvent whenever you want to perform an action in response to an event.



    因此, observeEvent需要用户做一个 Action 来运行里面的函数。在您的示例中,只有当用户手动更改输入“b”时,输入“a”才会更新,反之亦然。这就是为什么 observeEvent适用于这种情况和 observe才不是。

    编辑:使用 observe 时创建的循环的结果更清晰,这是 OP 中示例的略微修改版本:
    library(shiny)

    shinyApp(
    ui = fluidPage(
    numericInput('a','a', value = NULL, max = 1, min = 0),
    numericInput('b','b', value = NULL, max = 1, min = 0)
    ),
    server = function(input, output, session) {

    # Using a single observer ----
    observe({

    updateNumericInput(session, 'a', value = 1-req(input$b))

    updateNumericInput(session, 'b', value = 1-req(input$a))

    print(paste0("a = ", input$a))
    print(paste0("b = ", input$b))

    })


    # Using separate observers ----
    # observeEvent(input$b, {
    # updateNumericInput(session, 'a', value = 1-input$b)
    # })
    #
    # observeEvent(input$a, {
    # updateNumericInput(session, 'b', value = 1-input$a)
    # })

    }
    )

    小心解释: a 的起始值和 b被打印。然后, a 的新值和 b已创建,但新值 b取决于 a 的第一个值(不在 a 的第二个值上)。 a 的第三个值和 b将取决于 a 的第二个值和 b , 等等。

    关于R Shiny - 了解更新相互依赖的输入时观察和观察事件之间的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60413024/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com