如何在 Shiny 中对多个表进行排序

How to sort multiple tables in Shiny

有什么方法可以对 table 中的列和另一个 table 中的同一列进行排序?例如,在下面的代码中,我用 mtcars 数据绘制了两个数据table,我想通过单击对第一个 table 的列 mpg 进行排序,在第二个 [=13] 中显示相同的排序=] 自动,如果我点击第二个 table 也是一样,自动排序第一个 table.

library(DT)
library(shiny)

ui <- basicPage(
  h2("The mtcars data"),
  dataTableOutput("mytable"),
  br(),
  dataTableOutput("mytable2")
)

server <- function(input, output) {
  output$mytable = DT::renderDataTable({
    mtcars
  })
  output$mytable2 = DT::renderDataTable({
    mtcars
  })
}

shinyApp(ui, server)

我尝试将 stateSave 选项与 datatable 一起使用,我相信这可能会有所帮助。 order 选项可以保存在 reactiveValues 中,并在任一 table 的顺序更改时更新。在更改 reactiveValues 之前,我确保它是存储顺序的更改,否则您可能会重复更新 datatable。最后,因为状态将保存在 localStorage 中,所以添加 stateDuration = -1 将防止用户再次访问应用程序时进行额外排序。

server <- function(input, output, session) {
  
  rv <- reactiveValues(
    options = list(stateSave = TRUE,
                   stateDuration = -1,
                   order = list())
  )
  
  output$mytable = DT::renderDataTable({
    datatable(mtcars, options = rv$options)
  })
  
  output$mytable2 = DT::renderDataTable({
    datatable(mtcars, options = rv$options)
  })
  
  observeEvent(input$mytable_state$order, {
    if (!identical(rv$options$order, input$mytable_state$order)) {
      rv$options$order <- input$mytable_state$order
    }
  })
  
  observeEvent(input$mytable2_state$order, {
    if (!identical(rv$options$order, input$mytable2_state$order)) {
      rv$options$order <- input$mytable2_state$order
    }
  })
  
}

编辑:关于添加其他选项,您可以采用不同的方法。

首先,您可以向 rv 添加更多选项(例如,添加 pageLength):

rv <- reactiveValues(
    options = list(stateSave = TRUE,
                   stateDuration = -1,
                   pageLength = 5,
                   order = list())
)

或者,如果您想在 datatable 中添加 options,并且可能在两个 table 之间使用不同的选项,您可以改为存储 orderrv:

server <- function(input, output, session) {
  
  rv <- reactiveValues(
    order = list()
  )
  
  output$mytable = DT::renderDataTable({
    datatable(mtcars, options = list(
      stateSave = TRUE,
      stateDuration = -1,
      order = rv$order))
  })
  
  output$mytable2 = DT::renderDataTable({
    datatable(mtcars, options = list(
      stateSave = TRUE,
      stateDuration = -1,
      order = rv$order))
  })
  
  observeEvent(input$mytable_state$order, {
    if (!identical(rv$order, input$mytable_state$order)) {
      rv$order <- input$mytable_state$order
    }
  })
  
  observeEvent(input$mytable2_state$order, {
    if (!identical(rv$order, input$mytable2_state$order)) {
      rv$order <- input$mytable2_state$order
    }
  })
  
}

在这种情况下,rv$order 将仅存储 table 订单,而不是所有选项。