devdreamer
devdreamer

Reputation: 179

R shiny - updating CheckboxGroupInput based on another CheckboxGroupInput

I want to include the variables of 'Fixed Variables' in 'Random Variables' only when user uncheck the variables in Fixed Variables. Here's the image https://i.sstatic.net/3W1fZ.jpg. There is no error message, just that whenever I try to uncheck any of the variables, it doesn't let me to it. Can anyone please help me with this?

shinyServer(function(input, output,clientData, session) {
   observe({

     data<-reactive({
        file1<-input$file
        if(is.null(file1)){return()}
        read.table(file=file1$datapath,    sep=input$sep,header=input$header,stringsAsFactors=input$stringsAsFactors)
                  })

        colnames<-names(data())
        updateCheckboxGroupInput(session, "Fixed", choices = colnames, selected=colnames) 

        inputVar<-reactive({
              Fixedvar<-input$Fixed
              if(is.null(Fixedvar)){return()}
              subset<-data()[,!(colnames %in% Fixedvar)]
               col<-names(subset)
                col
                             })

       updateCheckboxGroupInput(session, "Random", choices = inputVar())
               })})



shinyUI(fluidPage(
        sidebarLayout(
              sidebarPanel( 

       fileInput("file","Please upload your file"),
       checkboxInput(inputId='header', label='header', value=TRUE),
       checkboxInput(inputId="stringsAsFactors", label="stringsAsFactors", value=FALSE),
        radioButtons(inputId='sep',label='Separator', choices=c(Comma=',',  Semicolon=';',Tab='\t',Space=''), selected=','),
        fluidRow(column(6, wellPanel(
        checkboxGroupInput("Fixed", 
                       label = "Fixed Variables","") 
           )),

        column(6, wellPanel(
        checkboxGroupInput("Random", label = "Random Variables","") 
         ) ))),


             mainPanel()
            )))

Upvotes: 1

Views: 3480

Answers (2)

Mikko Marttila
Mikko Marttila

Reputation: 11908

The problem is that you're only using the one observe. It runs whenever any reactive element inside it changes - in your case that's anything at all. Specifically, when you change the "Fixed" checkbox group, this part of the observe also runs again:

colnames<-names(data())
updateCheckboxGroupInput(session, "Fixed", choices = colnames, selected=colnames)

Since your data hasn't changed, it always just sets your choices and selected options to colnames. To get around it you need to make your server more modular, with separate observers and reactive elements. Here's a layout that works for your server.R:

library(shiny)

shinyServer(function(input, output, session) {

  data <- reactive({

    file1 <- input$file
    if(is.null(file1)){ return(mtcars) } # Default data for testing

    read.table(file = file1$datapath, sep = input$sep, header = input$header,
               stringsAsFactors = input$stringsAsFactors)

  })

  colnames <- reactive({ names(data()) })

  observeEvent(data(), {

    updateCheckboxGroupInput(session, "Fixed",
      choices = colnames(), selected = colnames()) 

  })

  inputVar <- reactive({

    Fixedvar <- input$Fixed

    if (setequal(colnames(), Fixedvar)) {
      # If sets are equal, return an empty string
      return("")
    } else {
      # Return elements that are only in colnames
      setdiff(colnames(), Fixedvar)
    }

  })

  observeEvent(inputVar(), {

    updateCheckboxGroupInput(session, "Random", choices = inputVar())

  })

})

I also changed the inputVar slightly. When none of the boxes are selected in a checkboxGroupInput, it returns NULL. So when input$Fixed is NULL, you actually want to update the options in "Random" to all of the columns.

There's still a problem though: whenever you check or uncheck a box in the first input, the second one gets updated. This means it's selections also get updated - to everything unchecked. It's a bit of a different problem though; I think you might be able to get around it using reactiveValues to store previous values of "Random" and using those as the initial values when you update the input choices.

Upvotes: 4

Julio Trecenti
Julio Trecenti

Reputation: 346

You may need observers. Whenever you want to evaluate reactive expressions, but do not need to return values, you have to use observers. Some observer-like examples are the renderXXX functions. More information here.

Try this

observe({
    colnames<-names(data())
    updateCheckboxGroupInput(session, "Fixed", choices = colnames, selected=colnames)
})

# ...

observe({
    iv <- inputVar()
    updateCheckboxGroupInput(session, "Random", choices = iv)
})

Upvotes: 0

Related Questions