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

时间:2016-07-21 18:24:19

标签: r shiny dt

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

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

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

上的数据集之后
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)

2 个答案:

答案 0 :(得分:6)

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

如果您担心较大数据集的性能问题,只需过滤反应式表达式中的数据,该表达式会缓存其输出。这样,您不会过滤超过输入$ 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"
    )
  })
}

答案 1 :(得分:1)

尽管接受的答案为shiny提供了可行的解决方案,但如何在带有flexdashboard的R Markdown文档中实现该解决方案尚不清楚。

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

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

shiny

这是输出的样子: enter image description here