如何在Shiny中访问/记住未经检查的值?

时间:2017-06-10 21:20:00

标签: r shiny

我正在摆弄R中的Shiny App。该应用程序已经

  • 选择列表输入A (主要组),可能的值为A,B 和/或C
  • 一组复选框输入b (子组),它们是 通过输入A 列表中的选择动态填充:chkb a和chkb b代表A,c代表d代表B,和/或e代表f代表C
  • 带有映射的数据框df

这是它的样子:

enter image description here

我的问题是输入b 忘记了,以前取消选中了这些复选框。因此 - 关于屏幕录制 - 必须使用列表输入A 中的每个新选项再次取消选中值 b

问:如何更改以下代码

  1. 输入A 中新添加的列表项仍然自动检查 输入b ,并且
  2. 输入b 以前的未经检查记住;至少只要输入A 中的相应类别未被取消选择
  3. 以下是代码:

    library(shiny)
    df <- data.frame(
      a = rep(LETTERS[1:3], each = 2), 
      b = letters[1:6]
    )
    
    ui <- fluidPage(
      column(6, selectInput("selectinput", "Input A", levels(df$a), multiple = T)),
      column(6, checkboxGroupInput("checkinput", "Input b", NULL))
    )
    
    server <- function(input, output, session) {
      observe({
        allPossibleB <- df$b[df$a %in% input$selectinput]
        updateCheckboxGroupInput(session, 
          "checkinput", "Input b",
          choices = allPossibleB,
          selected = setdiff(allPossibleB, NULL), # <=== previously unchecked instead NULL?
          inline = TRUE
        )
      })
    }
    
    shinyApp(ui, server)
    

    我尝试了几件事情,我认为这些事情并不值得一提,因为我对Shiny及其基本概念没有太多经验。也许有一种简单的方法来访问输入小部件的已检查值?

    提前感谢任何提示&amp;帮助!

2 个答案:

答案 0 :(得分:2)

您可以使用reactiveValues()来记住选中的值。

我对一个命名列表进行了编辑,以存储选中框的信息。如果您打算按字母顺序选择input A,那么这是必要的。

checked <- as.list(rep(T, length(df$b)))
names(checked) <- df$b

在应用内部,由于某种原因,您必须使用isolate()作为input$selectinput更新的速度超过input$checkinput,这会导致选择逻辑出现问题。因此,我们只想更新input$checkinput中的更改。好吧,我使用for循环来更新(未)检查值的列表:)。

  global <- reactiveValues(checked = checked)

  observe({
    input$checkinput
    isolate({
      if(!is.null(input$checkinput)){
        possible <- as.character(df$b[df$a %in% input$selectinput])
        for(nr in 1:length(possible)){
          global$checked[[possible[nr]]] <- (possible %in% input$checkinput)[nr]
        }
      }
    })
  })

完整的应用程序将是:

library(shiny)

df <- data.frame(
  a = rep(LETTERS[1:3], each = 2), 
  b = letters[1:6]
)

checked <- as.list(rep(T, length(df$b)))
names(checked) <- df$b


ui <- fluidPage(
  column(6, selectInput("selectinput", "Input A", levels(df$a), multiple = T)),
  column(6, checkboxGroupInput("checkinput", "Input b", NULL))
)

server <- function(input, output, session) {
  global <- reactiveValues(checked = checked)

  observe({
    input$checkinput
    isolate({
      if(!is.null(input$checkinput)){
        possible <- as.character(df$b[df$a %in% input$selectinput])
        for(nr in 1:length(possible)){
          global$checked[[possible[nr]]] <- (possible %in% input$checkinput)[nr]
        }
      }
    })
  })

  observe({
    allPossibleB <- df$b[df$a %in% input$selectinput]
    updateCheckboxGroupInput(session, 
                             "checkinput", "Input b",
                             choices = allPossibleB,
                             selected = df$b[unlist(global$checked)], # <=== previously unchecked instead NULL?
                             inline = TRUE
    )
  })
}

shinyApp(ui, server)

答案 1 :(得分:1)

column(6, updateCheckboxGroupInput("checkinput", "Input b", NULL, selected = input$checkinput))

或者如果您有'无'选项:

column(6, updateCheckboxGroupInput("checkinput", "Input b", NULL, selected = if(is.null(input$checkinput)){"none"}else{input$checkinput}))

为了保持它们与A,B,C分组,您可以创建reactiveValues来存储每个组的选项,并使用一个观察者来改变输入中的活动组。我很快就会发布代码 下面是承诺的代码,我的BigData回答的版本

library(shiny)
df <- data.frame(
a = rep(LETTERS[1:3], each = 2), 
b = letters[1:6]
)

ui <- fluidPage(
 column(6, selectInput("selectinput", "Input A", levels(df$a), multiple =  TRUE)),
 column(6, checkboxGroupInput("checkinput", "Input b", NULL))
 )

server <- function(input, output, session) {
checkin <- reactiveValues(A = NULL,B = NULL, C = NULL,puts = NULL)
observeEvent(input$selectinput,{
  if("A" %in% input$selectinput){
    checkin$A <- input$checkinput[which(input$checkinput %in% df$b[which(df$a[df$b] == "A")])]
  }
  if("B" %in% input$selectinput){
    checkin$B <- input$checkinput[which(input$checkinput %in% df$b[which(df$a[df$b] == "B")])]
  }
  if("C" %in% input$selectinput){
    checkin$C <- input$checkinput[which(input$checkinput %in% df$b[which(df$a[df$b] == "C")])]
  }
    checkin$puts <- c(if(!is.null(checkin$A)){checkin$A},if(!is.null(checkin$B)){checkin$B},if(!is.null(checkin$C)){checkin$C})
  })
observe({
 allPossibleB <- df$b[df$a %in% input$selectinput]
 updateCheckboxGroupInput(session, 
                         "checkinput", "Input b",
                         choices = allPossibleB,
                         selected = checkin$puts ,
                         inline = TRUE
 )
 })
 }

 shinyApp(ui, server)