【问题标题】:How to observe and track a single value from two renderUI elements in shiny如何在闪亮的两个 renderUI 元素中观察和跟踪单个值
【发布时间】:2019-03-25 16:00:18
【问题描述】:

这是一个简单的应用程序,用户可以在其中键入(numericInput,bpm_numeric)或滑动(sliderInput,bpm_slider)输入值。这两个 UI 元素都应与任一选择保持同步。但是,输出只需要跟踪一次。下面我跟踪它两次,但我只需要用户的“选择/输入”副本。我想我需要使用reactiveValues,但我不确定该方法。

library(shiny)

ui <- fluidPage(

    titlePanel("Reverb & Delay Calculator"),

    sidebarLayout(
        sidebarPanel(
            uiOutput("bpm_numeric"),
            uiOutput("bpm_slider")
        ),
        mainPanel(
            p("Numeric value is:"),
            verbatimTextOutput("numeric_val"),
            p("Slider value is:"),
            verbatimTextOutput("slider_val")
        )
    )
)

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

    output$bpm_numeric = renderUI({
        numericInput(
            "bpm_numeric",
            "BPM Numeric",
            value = 60, min = 40, max = 300
        )
    })

    output$bpm_slider = renderUI({
        sliderInput(
            "bpm_slider",
            "BPM Slider",
            value = 60, min = 40, max = 300
        )
    })

    # See how I can track "both", but really I only need to track "one" since
    # they should stay in-sync with one another. Maybe reactiveValues???
    output$numeric_val <- renderText({ input$bpm_numeric })
    output$slider_val <- renderText({ input$bpm_slider })

    observeEvent(input$bpm_numeric, {
        val = input$bpm_numeric
        updateSliderInput(session, "bpm_slider", value = val)
    })

    observeEvent(input$bpm_slider, {
        val = input$bpm_slider
        updateNumericInput(session, "bpm_numeric", value = val)
    })

}

shinyApp(ui = ui, server = server)

注意:虽然我目前使用的是uiOuput() + renderUI() + update___Input(),但这并不是必需的。我对其他方法持开放态度,只要输入 UI 保持同步我有一份同步输出的副本。

【问题讨论】:

  • 如果你只需要回复其中一个,为什么你有两个renderText 块? observeEvent 块确保它们保持同步,从那里任何需要该值的东西都应该能够仅依赖于其中一个。
  • 为什么不直接删除renderText 输出之一?
  • @r2evans - 我想我正在寻找概括而不是仅仅“选择”两者之一?我同意选择是任意的,但我想认为有一些方法可以抽象这个与锁定一个特定的选择?
  • 也许我错过了您所说的一些内容,但对我来说,通用解决方案正是“仅依赖其中一个”。在 SQL 中,您有 coalesce,它只为您提供其参数的第一个非空值;看起来你想要类似于这里的东西。坦率地说,我没有发现任何实用性,因为:(1)我知道所有候选人的 ID,因此可以选择一个,以及(2)我控制所有候选人的最新性。在一个更复杂的例子中,尝试有条件地依赖多个可能很容易导致重复依赖,最多会导致闪烁,可能是不必要的计算。
  • 您是想概括“如何使用该数字”,或者如何确保“2 或更多 UI 元素保持同步到相同的值”?

标签: r shiny reactive


【解决方案1】:

这是一个想法。它能够概括一点,但它仍然依赖于你完全知道你想以这种方式组合哪些 id。

对您当前示例的修改:

  1. 定义一个全局defbmp &lt;- 60,有助于确保所有元素都从同一个位置开始。
  2. 在新的useval 反应性之外,将所有input$bpm_numeric_slider 的引用替换为useval()
  3. 对状态跟踪有用,添加lastval反应值。
  4. 最后是useval &lt;- eventReactive({},{}) 块,具体取决于每个要同步的元素。

最终产品(不包括ui 组件,没有变化):

defbpm <- 60                                       # new

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

    output$bpm_numeric = renderUI({
        numericInput(
            "bpm_numeric",
            "BPM Numeric",
            value = defbpm, min = 40, max = 300    # update
        )
    })

    output$bpm_slider = renderUI({
        sliderInput(
            "bpm_slider",
            "BPM Slider",
            value = defbpm, min = 40, max = 300    # update
        )
    })

    output$numeric_val <- renderText({ useval() }) # update
    output$slider_val <- renderText({ useval() })  # update

    lastval <- shiny::reactiveVal(defbpm)          # new
    useval <- eventReactive({
      input$bpm_numeric
      input$bpm_slider
    }, {
      newval <- setdiff(c(input$bpm_numeric, input$bpm_slider), lastval())
      if (length(newval) > 0) {
        if (newval != input$bpm_numeric) updateNumericInput(session, "bpm_numeric", value = newval)
        if (newval != input$bpm_slider) updateSliderInput(session, "bpm_slider", value = newval)
        lastval(newval)
      }
      lastval()
    })                                             # new

}

改进方法(我目前不知道):

  1. 以编程方式定义要保持同步的元素,例如 character id 向量;
  2. 更新eventReactive 以编程方式生成条件表达式,我只是目前还不足以做到这一点;和
  3. 在运行时确定给定的 id 是否代表 numericInputsliderInput(或其他),以便可以更通用地调用 update* 函数。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-01-17
    • 2017-12-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多