约束多个滑块Input in SHILY使总和为100 [英] Constrain multiple sliderInput in shiny to sum to 100

查看:7
本文介绍了约束多个滑块Input in SHILY使总和为100的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一整天都在和这个问题作斗争,我差不多解决了它(可怕的黑客攻击)。但体验并不顺畅,且有副作用。

我想要的是三个滑块,范围从0到100,它们的总和应该始终是100。

这是其外观的屏幕截图

这是server.R闪亮代码。

library(shiny)

oldState<-NULL
newState<-NULL

getState<-function(input) c(input$slider1, input$slider2, input$slider3)

# Define server logic required
shinyServer(function(input, output, session) {

  observe({
    newState<<-getState(input)
    i<-which(oldState-newState != 0)[1]
    if(!is.na(i)){
      rem <- 100-newState[i]
      a<-sum(newState[-i])
      if(a==0) newState[-i]<<-rem/length(newState[-i])
      else newState[-i]<<-rem*(newState[-i]/a)
      for(j in 1:length(newState))
        if(j!=i)
          updateSliderInput(session, paste0("slider", j), value=newState[j])
    }
    oldState<<-newState
  })

  output$restable <- renderTable({
    myvals<-getState(input)
    myvals<-c(myvals, sum(myvals))
    data.frame(Names=c("Slider 1", "Slider 2", "Slider 3", "Sum"),
               Values=myvals)
  })
})

这里是ui.R闪亮代码

library(shiny)

# Define UI for application
shinyUI(pageWithSidebar(

  # Application title
  headerPanel("Sliders should sum to 100!"),

  # Sidebar with sliders whos sum should be constrained to be 100
  sidebarPanel(
    sliderInput("slider1", "Slider 1: ", min = 0, max = 100, value = 40, step=1),
    sliderInput("slider2", "Slider 2: ", min = 0, max = 100, value = 30, step=1),
    sliderInput("slider3", "Slider 3: ", min = 0, max = 100, value = 30, step=1)
  ),

  # Create table output
  mainPanel(
    tableOutput("restable")
  )
))

现在,除了两件事之外,它几乎完成了应该做的事情:

  • 感觉像是黑客,也就是说应该有更好的方法来做这件事
  • 当我将滑块移动到某个位置时,它有时会跳到稍低或稍高的位置。我不知道为什么。

如何解决这两个问题?

推荐答案

我认为使用dynamicUI可以解决您的问题。

如果您知道需要恰好有3个输入的总和为1,那么您可以将用户限制为只有两个滑块输入,并使第二个滑块输入取决于第一个滑块输入,如下所示。使用您的代码模板:

server.R

library(shiny)

# Define server logic required
shinyServer(function(input, output) {

  output$slider2 <- renderUI {
    sliderInput("slider2", "Slider 2", min = 0,  max = 100 - input$slider1, value = 0)  
  })

  output$restable <- renderTable({
    myvals<- c(input$slider1, input$slider2, 100-input$slider1-input$slider2)
    data.frame(Names=c("Slider 1", "Slider 2", "Slider 3"),
               Values=myvals)
  })
})

此处的关键是renderUI函数,该函数查找input$slider1值以约束slider2(因此slider3)的值

ui.R

library(shiny)

# Define UI for application
shinyUI(pageWithSidebar(

  # Application title
  headerPanel("Sliders should sum to 100!"),

  # Sidebar with sliders whos sum should be constrained to be 100
  sidebarPanel(
    sliderInput("slider1", "Slider 1: ", min = 0, max = 100, value = 0, step=1),
    uiOutput("slider2")
  ),

  # Create table output
  mainPanel(
    tableOutput("restable")
  )
))

如附图所示(如果您斜视),一旦将slider1设置为65,slider2将被限制为0-35。

这篇关于约束多个滑块Input in SHILY使总和为100的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆