简体   繁体   English

R Shiny 动态 DT 数据表记住过滤器/排序

[英]R Shiny dynamic DT Datatable remember filters/sorting

I'm building a R Shiny app with a dynamic datatable, using the DT package.我正在使用DT包构建一个带有动态数据表的R Shiny应用程序。 Users are able to select two columns within a data.frame that contains more columns.用户可以在包含更多列的 data.frame 中选择两列。

When users select a column, the datatable is updated and all filters/sorting are reset to default within the datatable object.当用户选择一列时,数据表会更新,所有过滤器/排序都将重置为数据表对象内的默认值。 How can I let the application remember filters and sorting when the given column is not replaced by the user?当给定的列未被用户替换时,如何让应用程序记住过滤器和排序?

Minimal working example below:下面的最小工作示例:

library(shiny)
library(DT)
library(data.table)


server <- function(input, output) {

  df <- data.frame(
    name = rep('a',20),
    dimA = 1:20,
    dimB = 21:40,
    dimC = 41:60
  )

  observe({
    columns <- c('name', input$dim1ID, input$dim2ID)
    dfDt <- df[names(df) %in% columns]

    output$dtDataTable = DT::renderDataTable(
      server = FALSE,

      expr = datatable(
        dfDt,
        filter = 'top',
        rownames = FALSE,
        selection = 'none',
        options = list(sDom  = '<"top">rt<"bottom">ip')
      )
    )
  })
}

ui <- fluidPage(
  sidebarLayout(
    sidebarPanel(
      ## Dimension 1
      selectInput(
        inputId = "dim1ID",
        label = "Dimensie 1",
        choices = c('dimA', 'dimB', 'dimC'),
        selected = 'dimA'
      ),
      ## Dimension 2      
      selectInput(
        inputId = "dim2ID",
        label = "Dimensie 2",
        choices = c('dimA', 'dimB', 'dimC'),
        selected = 'dimB'
      )
    ),
    mainPanel(DT::dataTableOutput('dtDataTable'))
  )
)

shinyApp(ui = ui, server = server)

This can be done using the DataTables Information , in particular the "state" information ( input$tableId_state ) which contains the order information of the current table, and input$tableId_search_columns which contains the filtering information by columns.这可以使用DataTables Information来完成,特别是包含当前表的顺序信息的“状态”信息( input$tableId_state )和包含按列过滤信息的input$tableId_search_columns If the columns are fixed (ie in the example above "Dimensie 1" and "Dimensie 2" would always be at the same place), it is much simpler to "remember" which one was ordered (unlike the original example where they are alphabetically reordered when the table is created).如果列是固定的(即在上面的示例中,“Dimensie 1”和“Dimensie 2”将始终位于同一位置),则“记住”已订购的列要简单得多(与按字母顺序排列的原始示例不同)创建表时重新排序)。 For instance based on the above example, the following will work if you sort the "A" column and change the right column from "B" to "C" and back:例如,基于上面的示例,如果您对“A”列进行排序并将右列从“B”更改为“C”并返回,则以下内容将起作用:

library(shiny)
library(DT)
library(data.table)


server <- function(input, output) {
    
    df <- data.frame(
        name = rep('a',20),
        dimA = 1:20,
        dimB = 21:40,
        dimC = 41:60
    )
    
    values <- reactiveValues(
        prevDim1 = "",
        prevDim2 = "",
        options = list(sDom  = '<"top">rt<"bottom">ip',
                       stateSave = TRUE,
                       order = list())
    )
    
    observeEvent(input$dtDataTable_state$order, {
        values$options$order <- input$dtDataTable_state$order
    })
    
    observeEvent({
        input$dim1ID
        input$dim2ID
    },{
        columns <- c('name', input$dim1ID, input$dim2ID)
        dfDt <- df[names(df) %in% columns]
        
        if(length(values$options$order) != 0 && ((values$prevDim1 != input$dim1ID && values$options$order[[1]][[1]] == 1) | (values$prevDim2 != input$dim2ID && values$options$order[[1]][[1]] == 2)) ){
            values$options$order = list()
        }
        
        values$prevDim1 <- input$dim1ID
        values$prevDim2 <- input$dim2ID
        
        output$dtDataTable = DT::renderDataTable(
            server = FALSE,
            
            expr = datatable(
                dfDt,
                filter = 'top',
                rownames = FALSE,
                selection = 'none',
                options = values$options
            )
        )
    })
}

ui <- fluidPage(
    sidebarLayout(
        sidebarPanel(
            ## Dimension 1
            selectInput(
                inputId = "dim1ID",
                label = "Dimensie 1",
                choices = c('dimA', 'dimB', 'dimC'),
                selected = 'dimA'
            ),
            ## Dimension 2      
            selectInput(
                inputId = "dim2ID",
                label = "Dimensie 2",
                choices = c('dimA', 'dimB', 'dimC'),
                selected = 'dimB'
            )
        ),
        mainPanel(DT::dataTableOutput('dtDataTable'))
    )
)

shinyApp(ui = ui, server = server)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM