如何实时刷新Shiny中的sliderInput()(不仅仅是滑动结束时)?

How to refresh sliderInput() in Shiny in real time (not only when the sliding ends)?

不好意思,不知道问题够清楚没有:在Shiny中,滑块每次滑动,只会在滑动结束时才计算更新值。如果我link它的值给图表,滑动的时候看起来不是很流畅(图表只会在松开鼠标或者几秒后变化,而不是随着滑动一直变化)。

使用滑动条改变y,图表中红点的位置也会改变。

Input and Chart

我的部分代码如下:

在ui.R中:

sliderInput("slider_mean", 
HTML("Try to change the value of ŷ:"),
min = 1, max = 200, value = 100,width="30%"),

plotlyOutput('meanplot'),

在server.R中:(这段代码可能不完整,只是举个例子)

  output$meanplot <- renderPlotly({
    
    meantb <- data.frame(y_hat = 1:200) %>%
      mutate(col2 =(y_mean1()-y_hat)^2+(y_mean2()-y_hat)^2+(y_mean3()-y_hat)^2+(y_mean4()-y_hat)^2+(y_mean5()-y_hat)^2+(y_mean6()-y_hat)^2)

    #Here is to input the slider value
    highlight_adjust <- meantb %>% 
      filter(y_hat %in% input$slider_mean)
    
    p=ggplot(meantb,
           aes(x = y_hat, y = col2)) + 
      
      geom_point(size =0.7,color="black") +
      
      geom_point(data=highlight_adjust, 
                 aes(x = y_hat, y = col2), 
                 color='red')+

      geom_line(size = 0.2,color="black") +
    ggplotly(p)
  })

来自 Shiny 的示例:

https://shiny.rstudio.com/gallery/slider-bar-and-slider-range.html

如果我们快速移动滑块,输出值会有延迟。

在阅读了一些 source code of sliderInput I found out that the default debounce behavior (cf. to the getRatePolicy section of this article) 之后,只有在 HTML 代码中没有 data-immediate 属性的情况下才会遵守滑块。

也就是说,我们只需要将这个属性添加到HTML,滑块就会立即做出反应。

注意。 如果您查看之前引用的源代码,您会发现 receiveMessage 会将 immediate 重置为 false。每当我们使用 updateSliderInput 时,都会调用 receiveMessage。因此,在调用 updateSliderInput 之后,我们必须重新分配 immediate 数据属性才能仍然看到行为。

在下面的示例中,您会看到被黑滑块的值会立即更新,而第二个滑块显示默认行为。单击 update 会将此行为作为一种附带损害,如果您想使用 updateSliderInput,您应该确保再次添加 data-immediate 属性(代码reset 按钮显示了一种可能的方法)。

但是请注意,shiny 团队没有向最终用户公开此功能很可能是有原因的,因此应将此解决方案视为 hack 并谨慎使用。 (从源代码来看,他们在使用 updateSliderInput(因此 receiveMessage)时使用 immediate 属性来否决默认速率策略。

library(shiny)
library(shinyjs)

my_sld <- function(...) {
   sld <- sliderInput(...)
   sld$children[[2]]$attribs$`data-immediate` <- "true"
   sld
}

shinyApp(
   fluidPage(
      useShinyjs(),
      my_sld("sld1", "Immediate:", 1, 10, 1), 
      verbatimTextOutput("dbg1"),
      sliderInput("sld2", "Debounced:", 1, 10, 1),
      verbatimTextOutput("dbg2"),
      actionButton("update", "Update kills Immediateness"),
      actionButton("reset", "Re-add immediate attribute")
      ),
   function(input, output, session) {
      output$dbg1 <- renderPrint(input$sld1)
      output$dbg2 <- renderPrint(input$sld2)
      observeEvent(input$update, {
         updateSliderInput(session, "sld1", value = 8)
      })
      observeEvent(input$reset, {
         runjs("$('#sld1').data('immediate', true);")
      })
   })