【问题标题】:What is the correct way to implement objects that depend on each others change in Shiny R?在 Shiny R 中实现相互依赖的对象的正确方法是什么?
【发布时间】:2020-01-03 10:45:42
【问题描述】:

我正在尝试使用Shiny。我习惯了其他编程语言(App Development 中的一点点 Java),其中有 onClick 事件,会触发其他变量的更改。我知道在 MVC 中,在视图元素发生更改后,控制器可以在后台更改模型变量,然后更新视图而不会触发其他元素上的事件无限循环。

这里的代码有效,但它触发了不必要的和不需要的循环:

如果您选择 49 作为 n,则数十个更改为 4,这将 n 更改为 48,这将更改为 4,这不会触发更改事件。

如果您随后将 n 更改为 49,则几十个更改为 4,这不会触发更改事件。

这似乎是浪费和资源密集型..

library(shiny)

ui <- fluidPage(
  sliderInput(inputId = "dozens",
              label = "Dozens:",
              min = 1,
              max = 5,
              value = 2),
  sliderInput(inputId = "n",
              label = "n:",
              min = 1,
              max = 60,
              value = 24)
)
server <- function(input, output,session) {
  observeEvent(input$dozens,{
    updateSliderInput(session,"n",value=12*input$dozens)
  })
  observeEvent(input$n,{
    updateSliderInput(session,"dozens",value=round(input$n/12))
  })
}

shinyApp(ui = ui, server = server)

正确的方法是什么?

【问题讨论】:

  • 不确定,但也许您可以使用 observeEvent(list(input$dozens,input$n),{ ...... } 并将两个 updateSliderInput 分组以代替 .......。对不起,如果它很傻,我没有尝试过。
  • 感谢您的想法。然后我需要区分这两个值中的哪一个在表达式内部发生了变化。我该怎么做?
  • 啊,是的,抱歉,这不是一个好主意。我需要醒来。我知道几天前有人问过类似的问题。
  • Here 我描述了一种区分哪个事件触发了观察者的可能性。或here 简化版。

标签: r shiny reactive observers


【解决方案1】:

observeEvent 是 Shiny 中的(某种)反模式。不要误会我的意思,它非常有用,不可或缺,我一直都在使用它。但是反应性通常在 Shiny 中效果更好,因为它不关心它,只以描述性的方式编写计算。

不过,在 OP 的情况下,我同意这似乎是不可能的。
输入之间的循环依赖尤其棘手。

一个不通用但可以在 OP 的情况下工作的解决方案是添加一个简单的if()

server <- function(input, output, session) {
  observeEvent(input$dozens, {
    if (round(input$n / 12) != input$dozens) {
      updateSliderInput(session, "n", value = 12 * input$dozens)
    }
  })

  observeEvent(input$n, {
    updateSliderInput(session, "dozens", value = round(input$n / 12))
  })
}

【讨论】:

  • 感谢您的建议。我认为,我现在的问题的抽象重新表述是,如果一个元素既可以是用户输入也可以是计算信息的输出,似乎在 Shiny 应用程序中不建议这样做。我的代码示例只是对我的实际问题的抽象,由于与变量“n”和“dozens”相关的函数更复杂,我不想经常执行它们。
  • 我明白了。您能想出一个稍微复杂一点的例子,使提议的解决方案不合适,以便我可以考虑更多吗?我也在考虑另一个闪亮的“反模式”,它允许更好地控制状态管理,“反应性值”,但很难抽象出一个例子,也许这根本不是你的用例。
  • 我什至可以告诉你我真正的问题。我得到了机器学习算法的结果,最简单的形式是一个数据框,其中包含用于真实标签的列(具有 A 和 B 级的因子)以及用于分类的 0 到 1 之间的浮点值。在三元组(阈值、灵敏度、特异性)中,每个值中的一个值决定其他两个值。然后阈值导致分类和绘图。我有用于计算其他三个值中的每一个的函数。用户应该能够放弃这三个值并立即查看其他两个值的结果。
  • 我明白了。我不知道这个问题的干净解决方案。你想出的是我看到的最常用的模式。 (可能在我的回答中进行了改编)。 @ismirsehregal 上面的建议看起来很有趣,但我没有尝试过,我不知道它的健壮性。
猜你喜欢
  • 2020-02-02
  • 1970-01-01
  • 2023-01-23
  • 2020-02-16
  • 1970-01-01
  • 1970-01-01
  • 2021-08-25
  • 2012-11-17
  • 1970-01-01
相关资源
最近更新 更多