如何在R Shiny中联动两个独立DT表格的列排序?
问题:Shiny中DT表格排序联动实现
在Shiny中使用DT::datatable()生成两个维度相同的表格,分别来自不同数据框,部分列名相同且展示在同一页面。需求如下:
- 点击其中一个表格的列头排序按钮进行升/降序排序时,另一个表格的对应列(按位置或名称)同步执行相同排序
- 两个表格的排序操作无先后限制
已通过DT::dataTableProxy实现分页联动,但未找到排序相关的直接配置项(ColReorder仅用于调整列顺序,不涉及列值排序),示例代码如下:
library(shiny) library(DT) ui <- fluidPage( h5("Table 1"), DTOutput("table1"), h5("Table 2"), DTOutput("table2") ) server <- function(input, output, session) { output$table1 <- renderDT({ datatable( iris[iris$Species == "setosa", ], options = list( dom = '<"top" p>', pageLength = 6) ) }) output$table2 <- renderDT({ datatable( iris[iris$Species == "virginica", ], options = list( dom = "t", pageLength = 6) ) }) table1Proxy <- dataTableProxy("table1") table2Proxy <- dataTableProxy("table2") observeEvent(input$table1_rows_current, { selectPage(table2Proxy, page = ceiling(max(input$table1_rows_current) / input$table1_state$length)) }) observeEvent(input$table2_rows_current, { selectPage(table1Proxy, page = ceiling(max(input$table2_rows_current) / input$table2_state$length)) }) } shinyApp(ui = ui, server = server)
解决方案
通过监听DT表格的排序状态输入(input$tableId_order),结合dataTableProxy的updateTableProxy方法实现排序同步,同时加入判断避免循环触发更新。
修改后的完整代码:
library(shiny) library(DT) ui <- fluidPage( h5("Table 1"), DTOutput("table1"), h5("Table 2"), DTOutput("table2") ) server <- function(input, output, session) { output$table1 <- renderDT({ datatable( iris[iris$Species == "setosa", ], options = list( dom = '<"top" p>', pageLength = 6) ) }) output$table2 <- renderDT({ datatable( iris[iris$Species == "virginica", ], options = list( dom = "t", pageLength = 6) ) }) table1Proxy <- dataTableProxy("table1") table2Proxy <- dataTableProxy("table2") # 分页联动(保留原有逻辑) observeEvent(input$table1_rows_current, { selectPage(table2Proxy, page = ceiling(max(input$table1_rows_current) / input$table1_state$length)) }) observeEvent(input$table2_rows_current, { selectPage(table1Proxy, page = ceiling(max(input$table2_rows_current) / input$table2_state$length)) }) # 排序联动:table1同步到table2 observeEvent(input$table1_order, { if (!identical(input$table1_order, input$table2_order)) { updateTableProxy(table2Proxy, order = input$table1_order) } }) # 排序联动:table2同步到table1 observeEvent(input$table2_order, { if (!identical(input$table1_order, input$table2_order)) { updateTableProxy(table1Proxy, order = input$table2_order) } }) } shinyApp(ui = ui, server = server)
关键说明
input$tableId_order:DT表格内置的排序状态输入,返回一个列表,每个元素为c(列索引, 排序方向),其中排序方向用"asc"(升序)、"desc"(降序)表示updateTableProxy:通过代理对象更新表格状态,order参数直接接收排序状态列表- 加入
!identical(input$table1_order, input$table2_order)判断:避免两个表格互相触发更新导致循环,仅当排序状态不一致时执行同步操作 - 支持多列排序:如果同时对多列进行排序,
input$tableId_order会包含多组排序规则,updateTableProxy会完整同步所有排序逻辑
内容的提问来源于stack exchange,提问作者Michael S Taylor
相关产品推荐
相关产品推荐

