Dynamic tag filtering in Shiny with AND and OR options

the simplest version of my question is this;

I want to create a filter in Shiny that would work like this...
0) A table is displayed with two columns, an ID_Col and a Tag col and a dropdown filter box.

  1. Users click into the filter box and all of the tags are available (as nothing is filtered). They can scroll or search to find their first tag selection.
    1 - output) The user selects their first tag. The table is filtered to show all IDs that meet that criteria, as well as every other row that belongs to that ID. AND the filter updates its Choices to only include relevant tags.
    ex: filtering for value "a" will return all 3 rows of ID_2 AND all 3 rows of ID_3. AND the search bar will update so that the second tag that can be selected will only be between the values "x", "y", and "n" As ID_2 and ID_3 have a row with a value of "a" and the tags related to ID_2 and ID_3 are "x", "y", and "n".
ID_Col | value
ID_1   | x
ID_1   | y
ID_1   | z
ID_2   | a
ID_2   | x
ID_2   | y
ID_3   | a
ID_3   | n
ID_3   | x
  1. The user selects a 2nd tag from the updated list and the above actions repeat.
    2 - output) The second tag is selected, the table is updated for only IDs that are related to tag_1 AND tag_2. The filter updates with only the relevant tags for IDs that are related to tag_1 AND tag_2.
    ex: if the user selects "y" as the second tag then the filter is searching for IDs where the ID is associated to both "a" AND "y". So the only ID to return from the above example is ID_2.

So it should work like the below in practice.

df <- 
  data.frame(ID_Col= c(rep("ID1", 3), rep("ID2", 3), rep("ID3", 3)),
       value= c("X", "Y", "Z", "X", "Y", "A", "A", "N", "X"))
# first filter returns both ID1 and ID2 because both ID have one row where value == "X"
df %>% 
  group_by(ID_Col) %>% 
  filter(any(value== "A"))
# this second filter will return only ID2 because only ID2 has a row where value == "X" AND a row where value == "A"
df %>% 
  group_by(ID_Col) %>% 
  filter(any(value== "A") & any(value== "Y"))

The more complex version of this question is that I have many types of tags with 1:1 and 1:many for example if we were talking recipes. In my 1:1 table I'd have recipe_ID, style (french OR japanese OR etc..), cook_duration etc. But then I'd have a 1:many table recipe_ID, ingredients.

The full question is how can I do the above, retain the choice updating, split out the types of tags into separate filters, AND have the search bars look for IDs where ALL of the tag conditions are met.

ex: I have a lot of a chicken to cook, select chicken as the first tag in ingredients. All recipes that use chicken show up. I also have a lot of onions. tag2 == onions. the table updates to only recipes with Chicken AND onions. I'm out of asian ingredients so I'll pick italian as my genre. the table updates to recipes that are Italian AND use chicken AND use onions.

To add another layer of complexity, it would be nice to choose between OR and AND when searching.

ex: I just got back from the Asian food store, now my search is recipes that are for Japanese OR Chinese where recipes have chicken AND onions.

Thank you in advance.

What have you tried so far? You make it seem like you haven't written a line of code towards your goals but would like someone to provide a complete solution....this is possible but seems unlikely, and is not in keeping with the culture. Therefore, you are encouraged to try to write code, and come back to us with specific problems where distinct technical issues outstrip your current abilities and you require support.

When you have a basis and require additional help could you please turn this into a self-contained REPRoducible EXample (reprex)? A reprex makes it much easier for others to understand your issue and figure out how to help.

If you've never heard of a reprex before, you might want to start by reading this FAQ:

Alternatively if you are very much a beginner, feel free to ask us to point you towards learning resources.

Hey thanks for replying.

I've written tried a bunch of different code and none of it worked, not even close to nearing the functionality I described. I've spent hours googling for variations of "tag filtering" for Shiny with no luck.

As for a reproducible example, I've provided that in my question already. But here it is again with the closest I've gotten. I found the shinywidgets library for dynamically self-filtering filters but I can't get it to perform as described.

df <- data.frame(ID_Col= c(rep("ID1", 3), rep("ID2", 3), rep("ID3", 3)),
       value= c("X", "Y", "Z", "X", "Y", "A", "A", "N", "X"))

ui <- 
  fluidPage(
    fluidRow(
      column(
        width = 10, offset = 1,
        tags$h3("example"),
        panel(
          selectizeGroupUI(
            id = "my-filters",
            inline = TRUE,
            params = list(
              value_filter = list(
                inputId = "value",
                title = "value filter"
                # placeholder = 'select'
              )
            )
          ),
          status = "primary"
        ),
        DTOutput("table")
      )
    )    
  )

server <- function(input, output, session) {
  
  ##### Filters
  res_mod <- callModule(
    module = selectizeGroupServer,
    id = "my-filters",
    data = df,
    vars = c("value")
  )
  output$table <- renderDT({
    res_mod()
  })

}
shinyApp(ui = ui, server = server)

This topic was automatically closed 54 days after the last reply. New replies are no longer allowed.

If you have a query related to it or one of the replies, start a new topic and refer back with a link.