Rachael
Rachael

Reputation: 315

How can I subset my dataframe based on the input of a checkbox in a shiny app?

I am working on a shiny app, I am trying to filter a dataframe based in the input of a checkbox, it is, if the check box is clicked the dataframe is filtered, else dataframe remains the same. If the checkbox is selected only those rows with value "YES" must be select in the column 'CANONICAL'

I have read similar questions (like here: Condition Filter in dplyr based on Shiny input) but I haven't been able to solve mine.

My code is as follows:

library(shiny)
library(DT) 
library(dplyr)
library(shinyWidgets)

options(shiny.maxRequestSize = 100*1024^2)

ui <- fluidPage(

  sidebarLayout(

    sidebarPanel(
      fileInput("file1", "Upload your File",
                multiple = FALSE,
                accept = c("text/csv",
                           "text/comma-separated-values,text/plain",
                           ".csv")),

      pickerInput("Consequence", "Consequence:",   
                  choices = c( "x", "y","z"), 
                  options = list(`actions-box` = TRUE),
                  multiple = TRUE ),
      prettyCheckbox(inputId= "CANONICAL", label = "CANONICAL", value =              FALSE, outline= TRUE, fill = TRUE, bigger = TRUE, status = 'success',width = NULL),

    mainPanel(
      dataTableOutput("contents")
    )

  ))

server <- function(input, output) {

  output$contents <- renderDT({
    req(input$file1)
    df <- read.delim(input$file1$datapath,
                     header = TRUE,
                     sep = '\t') 

    # Apply filters 
    df <- df %>% 
    filter(Consequence == input$Consequence ) %>%
    { if (input$CANONICAL) filter( CANONICAL == 'YES') }

return(df)

shinyApp(ui, server) 

The last filter does not work either if the condition is (input$CANONICAL), (input$CANONICAL == TRUE) or (!is.null(input$CANONICAL)). I have also tried to define the condition in a separate reactive function, but nothing seems to be working.

Upvotes: 2

Views: 1862

Answers (1)

TimTeaFan
TimTeaFan

Reputation: 18551

Please try next time to add a reproducible example with clean r code.

In the current form you cannot use the if-condition after the pipe operator.

I usually add the if condition in the filter statement. See code below. In this case you have to provide an else condition otherwise the code won't work.

Note that I have changed your example to make it reproducible.

library("shiny")
library(DT)
library(dplyr)
library(shinyWidgets)

## Only run examples in interactive R sessions

shinyApp(

    # options(shiny.maxRequestSize = 100*1024^2)

    ui = fluidPage(

        sidebarLayout(

            sidebarPanel(

                pickerInput("Consequence", "Consequence:",   
                            choices = c( "x", "y","z"), 
                            options = list(`actions-box` = TRUE),
                            selected = "x",
                            multiple = TRUE ),

                prettyCheckbox(inputId = "CANONICAL",
                               label = "CANONICAL",
                               value = FALSE,
                               outline = TRUE,
                               fill = TRUE,
                               bigger = TRUE,
                               status = 'success',width = NULL)),


            mainPanel(
                dataTableOutput("contents")
            )

            )
        ),

        server = function(input, output) {

            df <- data.frame(Consequence = c(rep("x",4),rep("y",4),rep("z",4)),
                          CANONICAL = rep(c("YES","NO"),6),
                             x1 = c(5,6,7,3,4,5,2,3,4,2,1,7),
                             x2 = c(1,2,3,2,3,2,1,4,6,7,3,4),
                             x3 = c(12,43,64,34,93,16,32,74,84,89,45,67)
                          )


            output$contents <- renderDT({

                print(input$CANONICAL)

            df <- df %>% 
                filter(Consequence == input$Consequence ) %>%
                filter(if (input$CANONICAL == TRUE) CANONICAL == "YES" else !is.na(CANONICAL))

            return(df)
            })
        }
)

Upvotes: 2

Related Questions