R语言 对表排序时,shinydatatable行id发生更改

r7s23pms  于 2023-06-27  发布在  其他
关注(0)|答案(1)|浏览(100)

我有一个闪亮的应用程序,其中渲染了使用nc数据集的数据表table。我想在单击actionButton()时选择row-id等于2的行,我的实现如下:

dataTableProxy("table") %>%
      # deselect any previously selected row
      selectRows(NULL) %>%
      # select row with id 2
      selectRows(which(input$table_rows_all == 2))

这工作得很好,但是在对表进行排序时,行为似乎变得随机。例如,当对列PERIMETER进行排序时,单击按钮会突出显示id == 15的行,这是排序表中的第五行,而我希望它仍然选择id == 2的行,在本例中是Alleghany县。我还添加了一个verbatimTextOutput(),以清楚地显示id == 15的行被选中。同样的随机行为也适用于基于其他列的排序。

我想实现的行为是,当表排序时,* 总是选择id为2的行 *,而不管它的位置如何。任何帮助都是非常感谢的。下面是我的代码的一个最小可重复的例子:

# Load packages ----
library(shiny)
library(sf)

# User interface ----
ui <- fluidPage(
  sidebarLayout(
    sidebarPanel(width=4,
      style = "height: 90vh; overflow-y: auto; margin: 0px;",
      actionButton("select",
                 label="Select row with id = 2")
    ),
    mainPanel(width=8,
              style = "margin: 0px;",
              "Table",
               tags$style('#table :is(th, td) {padding: 4px;}'),
               div(dataTableOutput(outputId = "table"), 
                   style = "height: calc(47vh); font-size: 75%; width: 100%;"),
              br(),
              br(),
              verbatimTextOutput('printfield')
    )
  )
)

# Server logic ----
server <- function(input, output) {
  nc <- st_read(system.file("shape/nc.shp", package="sf")) %>%
    st_transform(crs=4326)
  
  output$table <- DT::renderDataTable({DT::datatable(st_drop_geometry(nc),
                                                     selection= "single",
                                                     options = list(scrollX = TRUE,
                                                                    scrollY = "47vh",
                                                                    dom = 't',
                                                                    paging = FALSE))})
  observeEvent(input$table_rows_selected, {
    output$printfield <- renderPrint({input$table_rows_selected})
  })
  
  observeEvent(input$select, {
    if (input$select%%2==1) {
    dataTableProxy("table") %>%
      selectRows(NULL) %>%
      selectRows(which(input$table_rows_all == 2))
    }else{
      dataTableProxy("table") %>%
        selectRows(NULL)
    }
  })

}

# Run the app
shinyApp(ui, server)

编辑:找到解决方案

事实证明,我的问题的解决方案非常简单。而不是使用selectRows(which(input$table_rows_all == 2)),我应该简单地使用selectRows(2)

dataTableProxy("table") %>%
    selectRows(NULL) %>%
    selectRows(2)

由于某些原因,自动生成的行索引在调用input$table_rows_all时发生变化,这导致表排序时出现看似随机的行为。

rhfm7lfc

rhfm7lfc1#

有一个解决方案,带有Select扩展和rowId选项。但Select扩展需要server = FALSE

library(DT)
library(shiny)

rowNames = TRUE # whether to show row names
colIndex <- as.integer(rowNames)

dat = iris[1:5,]

dat[["rowId"]] <- paste0("row-", seq_len(nrow(dat)))

callback <- JS(
  '$("#btn").on("click", function() {',
  '  var index = $(nbr).val();',
  '  var rowId = "#row-" + index;',
  '  table.row(rowId).select();',
  '});'
)

ui <- fluidPage(
  br(),
  sidebarLayout(
    sidebarPanel(
      numericInput("nbr", "Choose a row", value = 1, min = 1, max= 5),
      br(),
      actionButton("btn", "Select this row")
    ),
    mainPanel(
      DTOutput("dtable")
    )
  )
)

server <- function(input, output, session) {

  output[["dtable"]] <- renderDT({
    datatable(
      dat,
      rownames = rowNames,
      extensions = "Select",
      selection = "none",
      callback = callback,
      options = list(
        rowId = JS(sprintf("function(data){return data[%d];}",
                          ncol(dat)-1L+colIndex)),
        columnDefs = list(
          list(visible = FALSE, targets = ncol(dat)-1L+colIndex),
          list(className = "dt-center", targets = "_all")
        ),
        select = TRUE
      )
    )
  }, server = FALSE)

}

shinyApp(ui, server)

相关问题