r - R Shiny:反应式 DF,根据反应式嵌套 IF 语句过滤
问题描述
我正在尝试创建一个应用程序,该应用程序接受输入文件并允许用户通过应用多个条件并选择要在选定列中查找的关键字来过滤它。
过滤逻辑:
在 textInput 小部件中输入关键字(以逗号分隔);通过 selectInput,选择列来检查这些关键字是否出现在其中任何一个中
在应用另一对带有 AND 或 OR 逻辑的 textInput+selectInput 条件之后
在第三个过滤器的选定列中排除包含关键字的行之后。
我附上了 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$keys2
,input$cols2
然后在 中选择 OR input$and_or
)
过滤器 3:从结果数据集中,排除“rm”列中包含“Mazda”的行(通过在input$keys3
和中输入数据input$cols3
)
我认为可以通过将每个过滤器的结果存储为索引向量,然后根据选定的 AND/OR 单选按钮将交集/单位应用于它们来完成。
理想情况下,我只想在按下 actionButton“过滤器”后运行过滤器。我还计划将过滤后的数据框存储为响应式对象,以便下载和汇总图表。
我真的很感激有人对如何实施此规则有想法/提示。
提前致谢!:)