首页 > 解决方案 > R Shiny:反应式 DF,根据反应式嵌套 IF 语句过滤

问题描述

我正在尝试创建一个应用程序,该应用程序接受输入文件并允许用户通过应用多个条件并选择要在选定列中查找的关键字来过滤它

过滤逻辑:

  1. 在 textInput 小部件中输入关键字(以逗号分隔);通过 selectInput,选择列来检查这些关键字是否出现在其中任何一个中

  2. 在应用另一对带有 AND 或 OR 逻辑的 textInput+selectInput 条件之后

  3. 在第三个过滤器的选定列中排除包含关键字的行之后。

我附上了 mtcars 的例子。我创建了 UI 和服务器代码:

library(shiny)
library(tidyverse)
library(stringr)
library(dplyr)
library(DT)
library(gridExtra)
library(gdata)
library(data.table)

df<- as.data.table(mtcars)

ui <- fluidPage(

   # Application title
   titlePanel("example"),

   # Sidebar with a slider input for number of bins 
   sidebarLayout(
      sidebarPanel(
        #WELL 1. KEYS FILTER
        wellPanel(textInput("keys1", label = h3("Enter keywords separated by     comma:"), placeholder = "Enter text..."),
                  selectInput("cols1", "Select variables:", choices=colnames(df), multiple=T)),

        #AND/OR SELECTOR CONNECTING 1st AND 2nd FILTERS
        radioButtons(inputId="and_or",
                     label="",
                     c("AND"="&", 
                       "OR"="|"),
                     selected="&", inline=T),

        #WELL 2. KEYS2 FILTER
        wellPanel(textInput("keys2", label = h3("Enter keywords separated by comma:"), placeholder = "Enter text..."),
                  selectInput("cols2", "Select variables:", choices=colnames(df), multiple=T)),

        #WELL 3. EXCLUDER FILTER
        wellPanel(textInput("excluders", label = h3("Enter keywords to exclude separated by comma:"), placeholder = "Enter text..."),
                  selectInput("cols_excl", "Select variables:", choices=colnames(df), multiple=T)),
        actionButton("keys_button", "Filter"), 
        width=3),

      mainPanel(
        tableOutput("summary"),
        DT::dataTableOutput("table")
      )
   )
)



server <- function(input, output) {

  #FILTER_INDEX1
  keys_vector1 <- reactive({
    paste0(unlist(trim(strsplit(input$keys1,","))), collapse = "|")
  })
  keys_index1 <- reactive({
    which(!!rowSums(sapply(df[input$cols1], grepl, pattern = keys_vector1(),     ignore.case = TRUE)))
  })

  #FILTER_INDEX2
  keys_vector2 <- reactive({
    paste0(unlist(trim(strsplit(input$keys2,","))), collapse = "|")
  })
  keys_index2 <- reactive({
    which(!!rowSums(sapply(df[input$cols2], grepl, pattern = keys_vector2(), ignore.case = TRUE)))
 })

  #FILTER_INDEX2
  keys_vector3 <- reactive({
    paste0(unlist(trim(strsplit(input$excluders,","))), collapse = "|")
  })
  keys_index3 <- reactive({
    which(!!rowSums(sapply(df[input$cols_excl], grepl, pattern = keys_vector3(), ignore.case = TRUE)))
  })   



#SUMMARY TABLE  
  output$summary<- renderTable({
        df%>%
    summarize("Number of observations"=n())
  })

#FILTERED DATATABLE
  output$table <- DT::renderDataTable({

    DT::datatable(df[,], options = list(searching = FALSE))
  })


}


shinyApp(ui = ui, server = server)

结果如下: 在此处输入图像描述

我现在正在努力让数据框根据 3 个连续的用户输入进行过滤。

这是我想做的例子:

过滤器 1:input$keys1过滤“carb”或“gear”列中包含数字“4”(输入到)的行(通过 选择input$cols1

过滤器 2:到结果数据集,在“am”列中添加也包含“0”的行(将数据输入到input$keys2input$cols2然后在 中选择 OR input$and_or

过滤器 3:从结果数据集中,排除“rm”列中包含“Mazda”的行(通过在input$keys3和中输入数据input$cols3

我认为可以通过将每个过滤器的结果存储为索引向量,然后根据选定的 AND/OR 单选按钮将交集/单位应用于它们来完成。

理想情况下,我只想在按下 actionButton“过滤器”后运行过滤器。我还计划将过滤后的数据框存储为响应式对象,以便下载和汇总图表。

我真的很感激有人对如何实施此规则有想法/提示。

提前致谢!:)

标签: rshinyreactivenested-if

解决方案


推荐阅读