约束多个滑块Input in SHILY使总和为100 [英] Constrain multiple sliderInput in shiny to sum to 100
本文介绍了约束多个滑块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屋!
查看全文