如何从筛选数据表 (DT) 的选定行中获取数据?
How do I get the data from the selected rows of a filtered datatable (DT)?
DT 包允许您使用 input$tableID_rows_selected
获取选定行的索引。这对于没有过滤数据的表非常有用。但是,如果我们有过滤后的数据集,我们就不能使用相同的方法,因为行索引已关闭。
那么对于过滤后的数据集,我们如何获取数据表中选中行的数据呢?
下面,我发布了一个基本的 shiny 应用程序,它显示了四个表:第一个是原始 mtcars 数据集,第二个获取第一个中的选定行。第三个和第四个做同样的事情,但是在 "filter" 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)
一种方法:在您的 filteredTable_selected() 函数中,您正在创建将放入第四个 DT 的数据,使用 filter(mtcars, cyl == input$filter)
就像您对第三个 [=18] 所做的那样=] 而不是 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"
)
})
}
虽然接受的答案为 shiny
提供了一个可行的解决方案,但如何在 flexdashboard
的 R Markdown 文档中实现它并不明显。
在Rmd
文档中,render*()
像DT::renderDataTable()
这样的函数通常是匿名使用的,但是possible显式地将它们赋值到output
槽中shiny
。在这种情况下,要使用 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 包允许您使用 input$tableID_rows_selected
获取选定行的索引。这对于没有过滤数据的表非常有用。但是,如果我们有过滤后的数据集,我们就不能使用相同的方法,因为行索引已关闭。
那么对于过滤后的数据集,我们如何获取数据表中选中行的数据呢?
下面,我发布了一个基本的 shiny 应用程序,它显示了四个表:第一个是原始 mtcars 数据集,第二个获取第一个中的选定行。第三个和第四个做同样的事情,但是在 "filter" 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)
一种方法:在您的 filteredTable_selected() 函数中,您正在创建将放入第四个 DT 的数据,使用 filter(mtcars, cyl == input$filter)
就像您对第三个 [=18] 所做的那样=] 而不是 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"
)
})
}
虽然接受的答案为 shiny
提供了一个可行的解决方案,但如何在 flexdashboard
的 R Markdown 文档中实现它并不明显。
在Rmd
文档中,render*()
像DT::renderDataTable()
这样的函数通常是匿名使用的,但是possible显式地将它们赋值到output
槽中shiny
。在这种情况下,要使用 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"
)
})
```
输出如下: