在 Shiny App 中为多个反应式 DF 创建通用过滤器

问题描述

我正在构建一个需要显示多个表的仪表板,每个表都有一个选项卡。数据都是相关的,我想要通用过滤器,应用时将过滤所有表。举一个简单的例子,假设我有以下汽车经销商的表格,其中包含有关客户、他们的车辆以及在车辆上执行的服务的信息:

客户 邮政编码 年龄
梅森 14350 44
多尔 14352 25
罗杰斯 14358 60
车辆 ID 型号 客户
355 翼豹 2015 梅森
1324 林务员 2020 多尔
121 凯美瑞 2018 罗杰斯
服务 ID 服务 车辆 ID
1 换油 355
2 刹车 355
3 传感器更换 355
4 换油 1324
5 刹车 121

我的目标是在 Shiny 应用程序的自己的选项卡中将这些表中的每一个显示为数据表。然后我想要基于关系过滤所有表的通用过滤器。例如,如果我将服务表过滤到换油,我希望服务表只过滤到换油,但也希望车辆和客户表根据车主/车辆是否满足换油标准进行过滤。

实现这一目标的最佳方法是什么?我试图动态地循环遍历这些数据集,并为每个数据集创建一个反应数据框以及一个输出表,但我正在努力解决如何同时将过滤器应用于所有数据框的问题。在通过为每个视图/框架选择特定列来创建视图的情况下,创建一个大型数据框架是否是更好的选择?

解决方法

library(tidyverse)
library(shiny)


customer <- 
tribble(
    ~Customer,~Zip_Code,~Age,'Mason',14350,44,'Dole',14352,25,'Rogers',14358,60
)

vehicle <- 
tribble(
    ~Vehicle_ID,~Model,~Year,~Customer,355,'Impreza',2015,1324,'Forester',2020,121,'Camry',2018,'Rogers'
) 
service <- 
tribble(
    ~Service_ID,~Service,~Vehicle_ID,1,'Oil Change',2,'Brakes',3,'sensor replacement',4,5,121
)



ui <- fluidPage(
        sidebarLayout(
            sidebarPanel(selectInput('filter_global','Select Service',choices = unique(service$Service),selected = NULL)),mainPanel(tabsetPanel(
                tabPanel('Service',tableOutput({'service_table'})),tabPanel('Vehicle',tableOutput({'vehicle_table'})),tabPanel('Customer',tableOutput({'customer_table'})) )
                )
            )
        
    
  
)

server <- function(input,output,session) {

    
    reactive_service      <- reactive({filter(service,Service == input$filter_global )})
    output$service_table  <- renderTable({reactive_service()})
      
    #semi join for keeping only one table but match the key
    reactive_vehicle      <- reactive({semi_join(vehicle,reactive_service(),by = 'Vehicle_ID')})
    output$vehicle_table  <- renderTable({reactive_vehicle()})
    
    reactive_customer     <- reactive({semi_join(customer,reactive_vehicle())})
    output$customer_table <- renderTable({reactive_customer()})
}

shinyApp(ui,server)