【问题标题】:Extract filters from R Shiny Datatable从 R Shiny Datatable 中提取过滤器
【发布时间】:2019-03-22 08:52:22
【问题描述】:

我在 R Shiny 中有一个 DT data table,我通过在 renderDT() 中设置 filter="top" 启用了列过滤。我现在想提取用户应用的过滤器,这样我就可以将它们保存在服务器端的变量中,并在——例如——更新数据库时重新应用它们。

这是一个使用 Shiny Dashboard 的 MWE:

library(shiny)           #  Shiny web app
library(shinydashboard)  #  Dashboard framework for Shiny
library(plotly)          #  Plotly interactive plots
library(DT)

ui <- dashboardPage(
  dashboardHeader(),
  dashboardSidebar(),
  dashboardBody(
    fluidRow(column(12, DTOutput("table")))
  )
)

server <- function(input, output, session) {
  fileData <- reactiveFileReader(1000, session, 'test.csv', read.csv)
  output$table <- renderDT(fileData(), filter = "top")
}

shinyApp(ui, server)

重申一下,我想将过滤器(例如,用户可能从其中一个过滤器框中选择一系列数值或特定因子)保存为 input$ 变量,以便我可以在服务器端。

【问题讨论】:

    标签: r shiny shinydashboard dt


    【解决方案1】:

    我认为最简单的方法就是添加

    options = list(stateSave = TRUE)
    

    renderDT() 函数中。然后,在server内,可以随时用input$&lt;tableID&gt;_state访问表的状态(我的表就叫“表”所以变成input$table_state

    observeEvent(input$table_state, {
      str(input$table_state)
    })
    

    那么整个解决方案是:

    library(shiny)
    library(shinydashboard)
    library(plotly)
    library(DT)
    
    ui <- dashboardPage(
      dashboardHeader(),
      dashboardSidebar(),
      dashboardBody(
        box(DTOutput("table"))
      )
    )
    
    server <- function(input, output, session) {
      fileData <- reactiveFileReader(1000, session, 'www/test.csv', read.csv)
      output$table <- renderDT(fileData(), filter = "top",
        options = list(stateSave = TRUE))
    
      observeEvent(input$table_state, {
        str(input$table_state)
      })
    
    }
    
    shinyApp(ui, server)
    

    RStudio 控制台中的示例输出:

    List of 6
     $ time   : num 1.54e+12
     $ start  : int 0
     $ length : int 10
     $ order  : list()
     $ search :List of 4
      ..$ search         : chr ""
      ..$ smart          : logi TRUE
      ..$ regex          : logi FALSE
      ..$ caseInsensitive: logi TRUE
     $ columns:List of 5
      ..$ :List of 2
      .. ..$ visible: logi TRUE
      .. ..$ search :List of 4
      .. .. ..$ search         : chr ""
      .. .. ..$ smart          : logi TRUE
      .. .. ..$ regex          : logi FALSE
      .. .. ..$ caseInsensitive: logi TRUE
      ..$ :List of 2
      .. ..$ visible: logi TRUE
      .. ..$ search :List of 4
      .. .. ..$ search         : chr "[\"0\"]"
      .. .. ..$ smart          : logi TRUE
      .. .. ..$ regex          : logi FALSE
      .. .. ..$ caseInsensitive: logi TRUE
      ..$ :List of 2
      .. ..$ visible: logi TRUE
      .. ..$ search :List of 4
      .. .. ..$ search         : chr "[\"8\"]"
      .. .. ..$ smart          : logi TRUE
      .. .. ..$ regex          : logi FALSE
      .. .. ..$ caseInsensitive: logi TRUE
      ..$ :List of 2
      .. ..$ visible: logi TRUE
      .. ..$ search :List of 4
      .. .. ..$ search         : chr ""
      .. .. ..$ smart          : logi TRUE
      .. .. ..$ regex          : logi FALSE
      .. .. ..$ caseInsensitive: logi TRUE
      ..$ :List of 2
      .. ..$ visible: logi TRUE
      .. ..$ search :List of 4
      .. .. ..$ search         : chr ""
      .. .. ..$ smart          : logi TRUE
      .. .. ..$ regex          : logi FALSE
      .. .. ..$ caseInsensitive: logi TRUE
    

    注意search 列表,其中显示了应用于每列的过滤器。

    奖金

    对于超级简单的过滤器提取,请使用input$table_search_columns。这与使用 sapply 的结果相同:

    sapply(input$table_state$columns, function(x) x$search$search)
    

    这将给出类似

    [1] ""        "[\"0\"]" "[\"8\"]" ""        ""      
    

    对于上面的例子。

    【讨论】:

    • 比我的回答好!
    • 感谢您指向input$table_serach_columns。很有用!知道如何解析输出(删除括号和引号),尤其是当每列选择多个特征时,例如"[\"AAK1\",\"AARS\"]"。期望的输出是 AAK1AARS
    • @cholland,我只是用了一些正则表达式
    【解决方案2】:

    可能有更简单的方法可以做到这一点,但这是我的 5 分钟快速解决方案:

    每次重绘表格时(当您更新过滤器时会发生这种情况,但也会在您排序、分页或执行任何其他导致重绘的操作时发生),注入一些 javascript 来查找您的过滤器的值'感兴趣。我们可以使用然后使用 this method 将值作为输入发送到 R 中闪亮应用程序的服务器端。

    我将使用 mtcars 数据集而不是 csv 文件,我使用的模板比您提供的模板稍微简单一些,并且我将专门寻找第三列的过滤值 disp .这应该足以帮助您解决您的具体案例。

    library(shiny)
    
    ui <- fluidPage(
      "disp filter:",
      textOutput("dispOut"),
      DT::dataTableOutput("table")
    )
    
    server <- function(input, output, session) {
      output$table <- DT::renderDataTable(
        DT::datatable(
          mtcars,
          filter = "top",
          options = list(
            drawCallback = JS('function(){ Shiny.onInputChange("dispFilter", this.api().table().columns(3).search()[0]); }')
          )
        )
      )
    
      output$dispOut <- renderText(input$dispFilter)
    }
    
    shinyApp(ui,server)
    

    编辑:@awwsmm 的另一个答案更好,这个更基于 javascript,另一个更闪亮

    【讨论】:

      猜你喜欢
      • 2019-09-14
      • 2018-06-18
      • 2021-01-26
      • 2020-03-02
      • 2019-07-26
      • 1970-01-01
      • 1970-01-01
      • 2020-08-15
      • 2018-10-11
      相关资源
      最近更新 更多