Mutually dependent numericInput in Shiny

Hey,

Please find the working code below.
Basically, there are 3 numericInputs which allows the user to change anyone at a time and the other 2 should adapt themselves resulting in 1

A + B + C = 1
However, since they are interlinked, they seems to be unstable.
How can we make it stable and allow the user to change any 1 variable: A and other 2 change themselves summing to 1.
similar question
similar1

library(shiny)
u <- shinyUI(fluidPage(
  titlePanel("Mutually Dependent Input Values"),
  sidebarLayout(
    sidebarPanel(
      numericInput("A", "A",.333),
      numericInput("B", "B",.333),
      numericInput("C", "C",.333)
    ),
    mainPanel(
      verbatimTextOutput("result")
    )
  )
)) 
s <- shinyServer(function(input, output,session) {
  
  observeEvent(input$A,{
    newB <- 1 - input$A - input$C 
    updateNumericInput(session, "B", value = newB) 
    newC <- 1 - input$A - input$B 
    updateNumericInput(session, "C", value = newC) 
  })
  observeEvent(input$B,{
    newC <- 1 - input$B - input$A 
    updateNumericInput(session, "C", value = newC) 
    newA <- 1 - input$B - input$C 
    updateNumericInput(session, "A", value = newA) 
  })
  observeEvent(input$C,{
    newA <- 1 - input$C - input$B 
    updateNumericInput(session, "A", value = newA) 
    newB <- 1 - input$C - input$C 
    updateNumericInput(session, "B", value = newB) 
  })


})
shinyApp(u,s)
1 Like

I've handled this situation with sliders where the 2nd slider depends on the first and the 3rd slider depends on the first 2. The third slider is disabled (using shinyjs package) so that the value is shown but can't be changed. Here is your example modified to show that approach:

library(shiny)
library(shinyjs)

u <- shinyUI(fluidPage(
  useShinyjs(),
  titlePanel("Mutually Dependent Input Values"),
  sidebarLayout(
    sidebarPanel(
      sliderInput("A", "A", min = 0, max = 1, value = 0.33, step = 0.01),
      sliderInput("B", "B", min = 0, max = 0.67, value = 0.33, step = 0.01),
      sliderInput("C", "C", min = 0, max = 1, value = 0.34, step = 0.01)
    ),
    mainPanel(
      verbatimTextOutput("result")
    )
  )
)) 

s <- shinyServer(function(input, output,session) {
  
  observeEvent(input$A,{
    updateSliderInput(session, "B", max = 1 - input$A)
    disable("C") # putting this here keeps the slider disabled all the time (but still shows updating)
  })
  
  observe({
    updateSliderInput(session, "C", value = 1 - input$A - input$B)
  })
  
})
shinyApp(u,s)
1 Like

Thanks for your time and support.

Since User has to have freedom to change any input was necessary.

Below is the code adapted to meet this requirement

ui <- fluidPage(
  column(6, 
         tags$h2("Set parameters"),
         numericInput("valueA", "Value1", value = .333, min = 0, max = 1, step = .1),
         numericInput("valueB", "Value2", value = .333, min = 0, max = 1, step = .1),
         numericInput("valueC", "Value3", value = .333, min = 0, max = 1, step = .1)
  ),
  column(6,
         uiOutput("ui")
  )
)

server <- function(input, output, session) {
  output$ui <- renderUI( {
    tagList(
      tags$h2("Display in %"),
      numericInput("obs1", "Label1", value = 100 * (input$valueA / (input$valueA + input$valueB + input$valueC))),
      numericInput("obs2", "Label2", value = 100 * (input$valueB / (input$valueA + input$valueB + input$valueC))),
      numericInput("obs2", "Label2", value = 100 * (input$valueC / (input$valueA + input$valueB + input$valueC)))
    )
  })
}

shinyApp(ui, server) 
1 Like

@hinkelman, Can you please help to ensure numericInput rendered using renderUI doesnt allow user to update the value i.e Although Label1,2 and 3 are calculated based on Value1,2 and 3, User can still increase or decrease the Label values. Can we somehow disable this. So that user cannot vary the Labels ?

This topic was automatically closed 54 days after the last reply. New replies are no longer allowed.