1

请在下面找到工作代码。基本上,有 3 个 numericInputs 允许用户一次更改任何人,另外 2 个应该适应自己导致 1

A + B + C = 1 但是,由于它们是相互关联的,因此它们似乎不稳定。我们如何使其稳定并允许用户更改任何 1 个变量:A 和其他 2 更改自己的总和为 1。

根据此处的答案,创建了一个工作代码,如下所示:

连接相互依赖的闪亮输入值

使用 R 的 Shiny 应用程序中的相关输入

library(shiny)
ui <- shinyUI(fluidPage(
  titlePanel("Mutually Dependent Input Values"),
  sidebarLayout(
    sidebarPanel(
      numericInput("A", "A",.333),
      numericInput("B", "B",.333),
      numericInput("C", "C",.333)
    ),
    mainPanel(
      verbatimTextOutput("result")
    )
  )
)) 
server <- 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(ui,server)

基本上,用户可以自由更新任何 numericInput:A、B 或 C。其他 2 个 numericInput 应自行调整以求和为 1。目前,由于它们是相互关联的,因此它们似乎不稳定(请找到上面的代码重新生成错误)

####### 不同的方法与自己的解决方案

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)   

4

1 回答 1

0

你需要做两件主要的事情:

  • 首先让您的初始值稳定,因此它们的总和应该为 1 (0.333, 0.333, 0.334 ),或者让初始值为空,这只有在您有某种类型的错误转义机制允许 NA 或空字符串时才有效作为初始值。正如我认为在任何情况下都应该验证输入是数字的那样,我选择使用第二个选项,这与验证效果很好。

  • 摆脱这些观察和更改输入的无限循环的第二种方法是一次更改一个,这意味着:

    • 如果A改变--->改变B,
    • 如果 B 改变 ---> 改变 C,并且
    • 如果 C 改变 ---> 改变 A

话虽如此,请注意更改输入的顺序在此方法中有所不同,这在开始时最明显,当您为输入提供第一组值时。

可能有更好的方法来解决这个问题,但这是我能想到的,所以就这样吧。

用户界面:

library(shiny)
ui <- shinyUI(fluidPage(
  titlePanel("Mutually Dependent Input Values"),
  sidebarLayout(
    sidebarPanel(
      numericInput("A", "A", NA),
      numericInput("B", "B", NA),
      numericInput("C", "C", NA)
    ),
    mainPanel(
      verbatimTextOutput("result")
    )
  )
)) 

服务器:

server <- shinyServer(function(input, output, session) {
  sum <- reactive({
    validate(
      need(is.numeric(input$A), 'A is not a number, only numbers are allowed'),
      need(is.numeric(input$B), 'B is not a number, only numbers are allowed'),
      need(is.numeric(input$C), 'C is not a number, only numbers are allowed')
    )
    input$A + input$B + input$C})

  observeEvent(input$A,{
      newB <- 1 - input$A - input$C
      updateNumericInput(session, "B", value = newB)
  })

  observeEvent(input$B,{
      newC <- 1 - input$B - input$A
      updateNumericInput(session, "C", value = newC)
  })

  observeEvent(input$C,{
      newA <- 1 - input$C - input$B
      updateNumericInput(session, "A", value = newA)
  })

  output$result <- renderPrint({
    print(sprintf("A=%.3f      B=%.3f      C=%.3f  ---->   A + B + C = %.0f", 
                  input$A, input$B, input$C, sum()))
  })
})

跑:

shinyApp(ui,server)
于 2019-04-26T07:52:33.180 回答