1

I am attempting to filter rows from a data frame, such as "mtcars", using the selectInput function in shiny. So a user will select which car he wants to view and the outputTable will show only stats from the selected car. In the selectInput example, the selection works on columns:

## Only run examples in interactive R sessions
if (interactive()) {

# basic example
shinyApp(
  ui = fluidPage(
    selectInput("variable", "Variable:",
                c("Cylinders" = "cyl",
                  "Transmission" = "am",
                  "Gears" = "gear")),
    tableOutput("data")
  ),
  server = function(input, output) {
    output$data <- renderTable({
      mtcars[, c("mpg", input$variable), drop = FALSE]
    }, rownames = TRUE)
  }
)
}

However, I am trying to use dplyr to filter out the cars based on the user input selected car:

library(shiny)
library(dplyr)

#####Just adding a column name to mtcars for the cars column####
#cars <- mtcars
#mtcars <-setNames(cbind(rownames(cars), cars, row.names = NULL), 
#                  c("cars", "mpg", "cyl", "disp", "hp", "drat", "wt", "qsec", "vs", "am", "gear", "carb"))

if (interactive()) {

  shinyApp(
    ui = fluidPage(
      selectInput("variable", "Pick a Car: ",
                  c("All" = "All Cars",
                    "Ford" = "Ford",
                    "Volvo" = "Volvo",
                    "Ferrari" = "Ferrari",
                    "Fiat" = "Fiat",
                    "Merc" = "Merc")),
      tableOutput("data")
    ),


    server = function(input, output) {

      output$cars <- renderText({
        mtcars %>%
          filter(mtcars$cars %in% as.character(input$variable))
      })

      output$data <- renderTable({
        output$cars
      })

    }
  )
}

Any suggestions will be much appreciated!

2 Answers 2

2

You only need renderTable() and pass it the filtered dataframe.
To filter the dataframe we need to find those rows where input$cars is present in the rowname (or the added column car).
But this won't work when selecting All, that's why we use the condition input$cars == 'All Cars'.

This should work:

shinyApp(
  ui = fluidPage(
    selectInput("cars", "Pick a Car: ",
                c("All" = "All Cars",
                  "Ford" = "Ford",
                  "Volvo" = "Volvo",
                  "Ferrari" = "Ferrari",
                  "Fiat" = "Fiat",
                  "Merc" = "Merc")),
    tableOutput("data")
  ),


  server = function(input, output) {

    mtcars$car <- rownames(mtcars)

    output$data <- renderTable({
      mtcars %>%
        filter(stringr::str_detect(car, as.character(input$cars)) | input$cars == 'All Cars')
    })

  }
)

enter image description here

Sign up to request clarification or add additional context in comments.

4 Comments

If you change stringr::str_detect(car..) to stringr::str_detect(cars..) it works.
@GGamba what if I want to use this technique to eliminate markers on a leaflet map, instead of a table?
While the underlying concept is the same, operating on a leaflet object can be a wildy different task, worth its own question
Seemed to have figured it out, but without your help it would not have been possible. Thank you!
1

First, the input$variable in your 2nd example is not known as your selectInput-ID is "cars". Then you dont use the renderedText output and so the filtering never happens. And last, the possible choices are not at hand in the mtcars data. So no matter what, it will never find any data for the table.

I wrote a reproducible example, changing the selectable choices to actual names of the mtcars data.

rm(list=ls())
cars <- mtcars
mtcars <-setNames(cbind(rownames(cars), cars, row.names = NULL),
                 c("cars", "mpg", "cyl", "disp", "hp", "drat", "wt", "qsec", "vs", "am", "gear", "carb"))
library(shiny)
library(DT)
if (interactive()) {

  shinyApp(
    ui = fluidPage(
      selectInput(inputId = "variable", label = "Pick a Car: ",choices = 
                    c("Mazda RX4 Wag" = "Mazda RX4 Wag",
                    "Merc 280" = "Merc 280",
                    "Volvo 142E" = "Volvo 142E",
                    "Duster 360" = "Duster 360",
                    "Lotus Europa" = "Lotus Europa"), selected = "Mazda RX4 Wag"),
      verbatimTextOutput("cars"),
      tableOutput("data")
    ),


    server = function(input, output) {

      carReact <- reactiveValues(car=NULL)

      output$cars <- renderText({
        txt <- mtcars[mtcars$cars %in% as.character(input$variable),]
        ## Use regex() or match() for example, if you only want partial matching of the car names.

        carReact$car <- txt
        paste(txt, collapse = ";")
      })

      output$data <- renderTable({
        req(carReact$car)
        datatbl <- carReact$car
        as.data.frame(datatbl)
      })

    }
  )
}

The selected Car name is saved in a reactiveValue (carReact) and it is assigned in the renderText function. And renderText is not able to print out lists, so you have to mere it to 1 variable or use the paste() function.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.