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

Jos*_*is 5 sorting datatable r shiny dt

有没有办法对表中的列和另一个表中的同一列进行排序?例如,在下面的代码中,我用 mtcars 数据绘制了两个数据表,我想通过单击对第一个表的列 mpg 进行排序,自动在第二个表中显示相同的排序,如果我单击第二个表,则相同,自动排序第一个表。

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)
Run Code Online (Sandbox Code Playgroud)

Ben*_*Ben 3

我尝试使用stateSave选项 withdatatable并相信这可能会有所帮助。该order选项可以保存reactiveValues并在任一表的顺序更改时更新。在更改 之前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
    }
  })
  
}
Run Code Online (Sandbox Code Playgroud)

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

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

rv <- reactiveValues(
    options = list(stateSave = TRUE,
                   stateDuration = -1,
                   pageLength = 5,
                   order = list())
)
Run Code Online (Sandbox Code Playgroud)

或者,如果您想添加 的options内部datatable,并且可能在两个表之间使用不同的选项,您可以存储orderin rv

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
    }
  })
  
}
Run Code Online (Sandbox Code Playgroud)

在这种情况下,rv$order将仅存储表顺序,而不是所有选项。