Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use dplyr conditional filter in reactive function in Shiny

I'm using dplyr in a Shiny app reactive function. I have an interactive widget in the UI that users can use to select status and data will be shown based on selected status. However I also want to give the option to show everything, which is a status that I have called 'All'.

I know how to achieve this without dplyr:

library(tibble)
library(shiny)

# Test Data -----
test_data <- tribble(
  ~id, ~status,
  1, 'active',
  2, 'inactive',
  3, 'test'
)

# Ui ----
ui = fluidPage(
  selectInput("status", "Choose a status:",
              choices = list("All","active","inactive","test")
  ),
  tableOutput('result')
)

# Server ----
server = function(input, output) {

  table <- reactive({
    if(input$status != 'All')
    {
      test_data <- test_data[test_data$status == input$status,]
    } else {
      test_data
    }
  })

  output$result <- renderTable(table(), rownames = FALSE)

}

# App ---
shinyApp(ui = ui, server = server)

However, I would like to be consistent with the rest of my code and use dplyr. Is there a way to do something like the below?

library(tibble)
library(dplyr)
library(shiny)

# Test Data -----
test_data <- tribble(
  ~id, ~status,
  1, 'active',
  2, 'inactive',
  3, 'test'
)

# Ui ----
ui = fluidPage(
  selectInput("status", "Choose a status:",
              choices = list("All","active","inactive","test")
  ),
  tableOutput('result')
)

# Server ----
server = function(input, output) {

  table <- reactive({
    test_data %>%
      filter(ifelse(input$status != 'All', status == input$status, status == ***pass***))
  })

  output$result <- renderTable(table(), rownames = FALSE)

}

# App ---
shinyApp(ui = ui, server = server)

In other words, is there a way to use ifelse inside filter function to not filtering under a certain condition?

Thanks!

like image 921
Giacomo Avatar asked Jan 04 '23 13:01

Giacomo


1 Answers

If your desire is to conditionally apply filter depending on the external value, you could attempt to use syntax:

TRUE

table <- reactive({
  test_data %>%
    filter(if(input$status != 'All')  (status == input$status) else TRUE)
}) 

Passing TRUE as condition would then not filter any rows.

{}

Alternative approach uses {} and returns untouched data set: else ..

table <- reactive({
  test_data %>%
  {if(input$status != 'All') filter(status == input$status) else .}
}) 

%<>%

Finally you could consider breaking the pipe and using %<>% operator available in magrittr package:

if(input$status != 'All') test_data %<>% filter(status == input$status)
like image 128
Konrad Avatar answered Jan 14 '23 13:01

Konrad