neversaint
neversaint

Reputation: 64074

How to make dplyr::filter from vector work in Shiny app

I have the following Rmarkdown:

---
title: "Untitled"
runtime: shiny
output: 
  flexdashboard::flex_dashboard:
    theme: bootstrap 
    orientation: columns
    vertical_layout: scroll
---

```{r setup, include=FALSE}
library(flexdashboard)
library(tidyverse)
```

Column {data-width=650}
-----------------------------------------------------------------------

```{r}

sidebarPanel( textInput("flowers", "flower name(s)", "virginica, setosa") )
mainPanel(
  renderPrint({
   flower_list <- unlist(lapply(strsplit(input$flowers, ",")[[1]], tolower))
   dat <- iris %>% filter(Species %in% flower_list)
   unique(dat$Species)
  })



)

```

Basically what it does is to take input from user and return list of names after filtering. But it seems that it doesn't work:

enter image description here

For example the main panel should return two values virginia setosa. What's the right way to do it?

In console it works fine:


library(dplyr)
#> 
#> Attaching package: 'dplyr'
#> The following objects are masked from 'package:stats':
#> 
#>     filter, lag
#> The following objects are masked from 'package:base':
#> 
#>     intersect, setdiff, setequal, union
dat <- iris %>% 
  filter(Species %in% c("virginica","setosa"))
unique(dat$Species)
#> [1] setosa    virginica
#> Levels: setosa versicolor virginica

Upvotes: 2

Views: 248

Answers (2)

akrun
akrun

Reputation: 887951

As there is only a single string, after splitting we get a list of length 1. It can be converted to a vector by extracting the first element ([[1]])

flower_list <- tolower(strsplit(input$flowers, ",\\s*")[[1]])

In addition, we also changed the split pattern by using a regex to match zero or more space (\\s*) after the comma (,)

With this change, the dashboard looks like

enter image description here

The output can be made to appear in the same order as in the textInput

 mainPanel(
   renderPrint({
    flower_list <- strsplit(input$flowers, ",\\s*")[[1]]
    iris %>% 
      filter(Species %in% flower_list) %>%
      mutate(Species = factor(Species, levels = flower_list)) %>%
      .$Species %>%
      levels
   })
 )

enter image description here

In the OP's post, as the other answer mentioned, we get a leading space for ' setosa' and it will not match when we are doing an exact match in the filter. The tolower is only required if the input string can have uppercase letters. In the example, it was not the case, so can be omitted.

Upvotes: 1

SBista
SBista

Reputation: 7704

That is because of the space between virginia and setosa in sidebarPanel( textInput("flowers", "flower name(s)", "virginica, setosa") ). You can either remove the space or remove the white spaces by modifying your code with something like this:

flower_list <- trimws(unlist(lapply(strsplit(input$flowers, ",")[[1]], tolower)))

Upvotes: 1

Related Questions