如何从筛选数据表 (DT) 的选定行中获取数据?

Posted

技术标签:

【中文标题】如何从筛选数据表 (DT) 的选定行中获取数据?【英文标题】:How do I get the data from the selected rows of a filtered datatable (DT)? 【发布时间】:2016-11-25 11:42:45 【问题描述】:

DT 包允许您使用input$tableID_rows_selected 获取选定行的索引。这对于没有过滤数据的表非常有用。但是,如果我们有一个过滤数据集,我们就不能使用同样的方法,因为行索引是关闭的。

那么,对于过滤后的数据集,我们如何获取数据表的选定行中的数据?

下面,我发布了一个基本的闪亮应用程序,它显示了四个表:第一个是原始 mtcars 数据集,第二个获取第一个中的选定行。第三个和第四个做同样的事情,但是在“过滤器”滑块输入上过滤数据集之后。

library(shiny)
library(DT)
library(dplyr)

ui <- fluidPage(
  DT::dataTableOutput("origTable"),
  DT::dataTableOutput("origTableSelected"),
  sliderInput("filter", label = "Filter by cyl", min = 4, max = 8, step = 2, value = 6),
  DT::dataTableOutput("filteredTable"),
  DT::dataTableOutput("filteredTableSelected")
)


server <- function(input, output, session) 

  output$origTable <- DT::renderDataTable(
    datatable(
      mtcars,
      selection = list(mode = "multiple"),
      caption = "Original Data"
    )
  )

  origTable_selected <- reactive(
    ids <- input$origTable_rows_selected
    mtcars[ids,]
  )

  output$origTableSelected <- DT::renderDataTable(
    datatable(
      origTable_selected(),
      selection = list(mode = "multiple"),
      caption = "Selected Rows from Original Data Table"
    )
  )

  output$filteredTable <- DT::renderDataTable(
    datatable(
      filter(mtcars, cyl == input$filter),
      selection = list(mode = "multiple"),
      caption = "Filtered Table (based on cyl)"
    )
  )

  filteredTable_selected <- reactive(
    ids <- input$filteredTable_rows_selected
    mtcars[ids,]
  )

  output$filteredTableSelected <- DT::renderDataTable(
    datatable(
      filteredTable_selected(),
      selection = list(mode = "none"),
      caption = "Table that gets data from unfiltered original data"
    )
  )


shinyApp(ui = ui, server = server)

【问题讨论】:

【参考方案1】:

一种方法:在您的filteredTable_selected() 函数中,您将在其中创建将放入第四个DT 的数据,使用filter(mtcars, cyl == input$filter) 就像您对第三个表所做的那样,而不是mtcars。这样,行索引将匹配。

如果您担心较大数据集的性能问题,只需在反应式表达式中过滤数据,该表达式会缓存其输出。这样,您过滤的内容不会超过您的 input$filter 值更改。

server <- function(input, output, session) 
  filteredTable_data <- reactive(
    filter(mtcars, cyl == input$filter)
  )

  output$filteredTable <- DT::renderDataTable(
    datatable(
      filteredTable_data(),
      selection = list(mode = "multiple"),
      caption = "Filtered Table (based on cyl)"
    )
  )

  filteredTable_selected <- reactive(
    ids <- input$filteredTable_rows_selected
    filteredTable_data()[ids,]
  )

  output$filteredTableSelected <- DT::renderDataTable(
    datatable(
      filteredTable_selected(),
      selection = list(mode = "none"),
      caption = "Table that gets data from unfiltered original data"
    )
  )

【讨论】:

我正在写一个问题,然后想通了。我想我会发布它,以便其他人知道。 blog.***.com/2011/07/… 如果要获取与原始data.frame相同的顺序选择的行,则需要对索引进行排序,例如:filteredTable_data()[sort(ids),]【参考方案2】:

虽然接受的答案为shiny 提供了一个可行的解决方案,但如何在带有flexdashboard 的R Markdown 文档中实现它并不明显。

Rmd 文档中,render*() 之类的DT::renderDataTable() 函数通常是匿名使用的,但将它们显式分配给shiny 中的output 槽是possible。在这种情况下,要使用input$tableID_rows_selected 构造,必须这样做。

此解决方案还对索引进行排序,以始终保持与原始数据框中相同的顺序。

---
title: "MRE"
author: ""
output: 
  flexdashboard::flex_dashboard:
    orientation: columns
    vertical_layout: scroll
runtime: shiny
---

Page data-orientation=columns
=======================================================================

Column data-width=650
-----------------------------------------------------------------------

### .

```r
  require(DT)
  library(dplyr)
  library(tibble)

  sliderInput("filter", label = "Filter by cyl", min = 4, max = 8, step = 2, value = 6)


  filteredTable_data <- reactive(
    mtcars %>% rownames_to_column() %>%  ##dplyr's awkward way to preserve rownames
          filter(., cyl == input$filter) %>% column_to_rownames()
  )

  ##explicit assignment to output ID
  DT::dataTableOutput("filteredTable")
  output$filteredTable <- DT::renderDataTable(
    datatable(
      filteredTable_data(),
      selection = list(mode = "multiple"),
      caption = "Filtered Table (based on cyl)"
    )
  )

  filteredTable_selected <- reactive(
    ids <- input$filteredTable_rows_selected
    filteredTable_data()[sort(ids),]  ##sort index to ensure orig df sorting
  )

  ##anonymous
  DT::renderDataTable(
    datatable(
      filteredTable_selected(),
      selection = list(mode = "none"),
      caption = "Table that gets data from unfiltered original data"
    )
  )

```

以下是输出的样子:

【讨论】:

以上是关于如何从筛选数据表 (DT) 的选定行中获取数据?的主要内容,如果未能解决你的问题,请参考以下文章

如何从我的 jquery 函数中获取表行中选定选项的值

使用 Javascript/jquery 如何从选定行中的每个单元格获取值

如何从选定的表行中获取最小和最大数量?

Web2py 数据库:如何从选定的行中选择行的子集?以及如何将它传递给 JavaScript?

如何将单击/选定的行数据从一个表传递到并排放置的另一个表

如何在Shiny R中丢弃DT :: datatable上的用户编辑