【问题标题】:How do I get the data from the selected rows of a filtered datatable (DT)?如何从筛选数据表 (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)

【问题讨论】:

    标签: r shiny dt


    【解决方案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.stackoverflow.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"
        )
      })
    
    ```
    

    以下是输出的样子:

    【讨论】:

      猜你喜欢
      • 2015-06-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-04-08
      • 2016-05-14
      • 1970-01-01
      • 2015-08-25
      • 2012-08-09
      相关资源
      最近更新 更多