Locking the limit of one widget (Shiny) as a function of another

Asked

Viewed 54 times

2

I tried to stop the limit of one widget based on the change of another. Suppose these two cases:

First case: The sum of two buttons cannot exceed the value 100. For example, when I put the value 60 on a button (called Price 1), another button (called Price 2) shall never exceed the 40. And vice versa.

Second case: The value of a button cannot be greater than or equal to the value of another button. For example, when I move the metric of Price 1 for 70, Price 2 can never pass the value 69. The opposite is also true.

My code (written in Rmarkdown) is this:

---
title: "Untitled"
runtime: shiny
output: 
  flexdashboard::flex_dashboard:
    orientation: rows
    vertical_layout: fill
---

```{r}
df_1 <- data.frame(
  m = .01, 
  d = .02, 
  q = 1
)

dis <- function(mc, desc, qtde) {
  ((((mc) / (mc - desc)) - 1) * qtde + qtde)
}

prp <- dis(
  mc = df_1$m, 
  desc = df_1$d, 
  qtde = df_1$q
)
```

```{r FRONT-END}
library(flexdashboard)
library(shiny)
library(scales)
```

Stack Overflow
=================================

Sidebar{.sidebar data-width=290}
--------------------------------

```{r}
sliderInput(
  inputId = 'm', label = 'Price 1', 
  value = 50, 
  min = 0, 
  max = 100, 
  step = 5
)

sliderInput(
  inputId = 'd', label = 'Price 2', 
  value = 25, 
  min = 0, 
  max = 100, 
  step = 5
)
```

This will help the user to guide themselves without having someone who knows R close by. Sometimes, even leaving a recommendation to the layperson, she can err (which is normal).

1 answer

1


What you need to do is include an observer in sliders. This can be done with observe() or with observeEvent() (which I recommend in this case).

When the observed event occurs what we will do is update the other slider. For that we use updateSliderInput().

Then we will add the excerpt below app

observeEvent(input$m, {
  updateSliderInput(session, inputId = "d", max = 100 - input$m)
})

observeEvent(input$d, {
  updateSliderInput(session, inputId = "m", max = 100 - input$d)
})

What we do for each case is to observe one of the sliders and, based on the values the users choose, update as much as possible in the other slider.

The whole app code looks like this:

---
title: "Untitled"
runtime: shiny
output: 
  flexdashboard::flex_dashboard:
    orientation: rows
    vertical_layout: fill
---

```{r}
df_1 <- data.frame(
  m = .01, 
  d = .02, 
  q = 1
)

dis <- function(mc, desc, qtde) {
  ((((mc) / (mc - desc)) - 1) * qtde + qtde)
}

prp <- dis(
  mc = df_1$m, 
  desc = df_1$d, 
  qtde = df_1$q
)
```

```{r FRONT-END}
library(flexdashboard)
library(shiny)
library(scales)
```

Stack Overflow
=================================

Sidebar{.sidebar data-width=290}
--------------------------------

```{r}
sliderInput(
  inputId = 'm', label = 'Price 1', 
  value = 50, 
  min = 0, 
  max = 100, 
  step = 5
)

sliderInput(
  inputId = 'd', label = 'Price 2', 
  value = 25, 
  min = 0, 
  max = 100, 
  step = 5
)

observeEvent(input$m, {
  updateSliderInput(session, inputId = "d", max = 100 - input$m)
})

observeEvent(input$d, {
  updateSliderInput(session, inputId = "m", max = 100 - input$d)
})
```

Browser other questions tagged

You are not signed in. Login or sign up in order to post.