简体   繁体   中英

R shiny bi-directional reactive widgets

I am struggling to figure out how to get 2 R Shiny widgets to update each other. For example, a slider widget that can update a text box widget, and visa versa, where the end user can choose to use either widget.

This question is similar, but has no answer, so I am giving what is (hopefully) a simpler example. Retrieving reactive dependencies as inferred by shiny::reactive() . If this question is answered elsewhere, I have been unable to find such an answer.

I would like to know if I can move slider1 to move slider2 and slider2 to move slider1. Right now I only can do the first part (I can move slider1 to move slider2). If I can do this, I am thinking I could make widget 1 a slider, and widget 2 a numerical input, with much the same code.

The below example was modified from http://shiny.rstudio.com/gallery/update-input-demo.html and it is as minimal an example as I could make. It was also the only app I could find that came close to what I was looking for, although I realize a very different approach may needed...

Server.R Code

shinyServer(
  function(input, output, clientData, session) {

#### one way interaction between slider 1 and 2 ####
    observe({![enter image description here][1]   
      c_label <- input$control_label
      c_num <- input$control_num  # <- input$inSlider

      # Slider input =============================================
      updateSliderInput(session, "inSlider",
                        label = paste("Slider2", c_label),
                        value = c_num)
      updateSliderInput(session, "control_num",
                        label = paste("Slider1", c_label),
                        value = c_num)
    })
})

Ui.r Code

shinyUI(fluidPage(
  titlePanel("One Way Reactive Slider"),
  fluidRow(
    column(3,
           wellPanel(
             h4("Slider Inputs"),
             sliderInput("control_num",
                         "This controls values:",
                          min = 1, max = 20, value = 15),
             sliderInput("inSlider", "Slider input:",
                          min = 1, max = 20, value = 15)
    ))

  )
))

下面是运行时应用程序的图片。移动滑块1移动滑块2,但相反的情况不正确(这是我想要做的)。

The trick is to create a dynamic UI. In this way, you can update a slider-drawing expression on changes in the other UI elements and rebuild a slider widget using a different default value:

server.R

shinyServer(
    function(input, output, clientData, session) {

    output$slider1 <- renderUI({
       slider2.value <- input$inSlider
       default.slider1 <- if (is.null(slider2.value)) 15 else slider2.value
       sliderInput("control_num",
                   "This controls values:",
                    min = 1, max = 20, value = default.slider1)
    })

    output$slider2 <- renderUI({
       slider1.value <- input$control_num
       default.slider2 <- if (is.null(slider1.value)) 15 else slider1.value
       sliderInput("inSlider", "Slider input:",
                    min = 1, max = 20, value = default.slider2)
    })

  })

ui.R

    shinyUI(fluidPage(
      titlePanel("One Way Reactive Slider"),
      fluidRow(
        column(3,
               wellPanel(
                 h4("Slider Inputs"),
                 uiOutput('slider1'),
                 uiOutput('slider2')
        ))

      )
    ))

If you enclose each input slider under a reactive observe, you can achieve your goal. This not only works for two inputs, but for several inputs as well. Let me explain by an example:

observe({
# Create a reactive relationship with slider1
input$slider1
# Update the second slider - slider2
updateTextInput(session, "slider2", NULL, input$slider1)
)}

Similarly for second input, you'd have to repeat the code, by:

observe({
# Create a reactive relationship with slider2
input$slider2
# Update the second slider - slider1
updateTextInput(session, "slider1", NULL, input$slider2)
)}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM