首页 > 解决方案 > 使 DT 表内过滤器响应子集数据

问题描述

我正在创建一个表,我希望用户能够首先使用小部件过滤数据以减少数据集,但仍希望用户能够使用内置的 DT 过滤器来进一步减少数据。但是,当采用这种方法时,我发现内置过滤器仍然包含存在于原始数据集中的值,而这些值实际上并不存在于传递以进行渲染的数据中。

例如,在这种情况下,表中仅包含“setosa”和“versicolor”,但“virginica”仍然是内置过滤器中的一个选项。

问题示例图像

有没有办法让内置过滤器只包含输入数据集中存在的选择?

这是演示该问题的示例代码:

##### Load Libraries #####
library(shiny)
library(shinyWidgets)
library(shinythemes)
library(DT)
library(shinyBS)
library(rgdal)
library(tidyverse)
library(shinyjs)

ui <- fluidPage(
  mainPanel(
    pickerInput("SpeciesPick","Select Species",choices=c("setosa","versicolor","virginica"),multiple=TRUE),
    div(DT::dataTableOutput("Table1"),filter="top")
    
  )
)

server <- function(input, output) {
  
  iris1<-reactive(iris[,])
  iris2<-reactive({iris1()%>%filter(Species%in%input$SpeciesPick)})
  
  #### Datatable 1 #####
  
  output$Table1<-DT::renderDT(
    iris2(),extensions=c('Buttons','Select','Scroller'),
    options=list(
      scrollX=TRUE,
      scrollY=400,
      scroller=TRUE,
      select=list(style='os',items='row'),
      dom='Blfrtip',
      buttons = list(list(extend='selectAll',className='selectAll',
                          text="Select All Visible",
                          action=DT::JS("function () {
                            var table = $('#Table1 table.dataTable').DataTable();
                            table.rows({ search: 'applied'}).deselect();
                            table.rows({ search: 'applied'}).select();
            }")
      ), list(extend='selectNone',className='selectNone',
              text="Deselect All Visible",
              action=DT::JS("function () {
                            var table = $('#Table1 table.dataTable').DataTable();
                            table.rows({ search: 'applied'}).select();
                            table.rows({ search: 'applied'}).deselect();

            }")
      ),'selectAll','selectNone','copy','csv')),
    selection='none',
    class="display nowrap compact",
    filter="top",
    server = FALSE
  )
}

shinyApp(ui = ui, server = server)

标签: rfiltershinyreactivedt

解决方案


那是因为iris$Species是一个因子,DT 过滤器使用这个因子的水平,它仍然是setosavirginica并且versicolordplyr过滤之后,即使它们中的一些出现 0。要删除 0 次出现的级别,请使用以下droplevels函数:

iris2 <- reactive({
  droplevels(iris1() %>% filter(Species %in% input$SpeciesPick))
})

推荐阅读