Shiny中rhandsontable排序后删除行如何保留自定义层级?
解决Shiny应用删除行后保留自定义层级的问题
你的核心问题出在删除行的逻辑中——代码强制用row_number()重新生成了tiers列,同时后续的排序逻辑也打乱了用户设置的层级关系。只需要修改删除行的处理代码,保留原有的tiers值即可解决问题:
修改后的完整代码
library(shiny) library(rhandsontable) library(shinyjs) library(dplyr) cars_data <- mtcars %>% mutate(tiers = row_number()) %>% relocate(tiers, .before = mpg) shinyApp( ui = fluidPage( useShinyjs(), helpText("Edit the table values in the 'Tiers' column to sort the table."), actionButton(inputId = "sort_button", label = "Sort Table"), actionButton(inputId = "remove_row_button", label = "Remove Row From Table", disabled = ''), br(), br(), rHandsontableOutput("cars_table") ), server = function(input, output, session) { cars_rv <- reactiveValues( table = cars_data, original_order = 1:nrow(cars_data) ) output$cars_table <- renderRHandsontable({ rhandsontable(data = cars_rv$table, selectCallback = TRUE) %>% hot_col("mpg", colWidths = 75, readOnly = T) %>% hot_col("cyl", colWidths = 75, readOnly = T) %>% hot_col("disp", colWidths = 90, readOnly = T) %>% hot_col("hp", colWidths = 90, readOnly = T) %>% hot_col("drat", colWidths = 75, readOnly = T) %>% hot_col("wt", colWidths = 75, readOnly = T) %>% hot_col("qsec", colWidths = 90, readOnly = T) %>% hot_col("vs", colWidths = 75, readOnly = T) %>% hot_col("am", colWidths = 75, readOnly = T) %>% hot_col("gear", colWidths = 75, readOnly = T) %>% hot_col("carb", colWidths = 75, readOnly = T) }) observe({ if (!is.null(input$cars_table_select$select$r)) { shinyjs::enable("remove_row_button") } }) observeEvent(input$remove_row_button, { selected_rhands_rows <- input$cars_table_select$select$r # 直接删除选中行,保留原有tiers值 cars_rv$table <- cars_rv$table %>% slice(-c(selected_rhands_rows)) output$cars_table <- renderRHandsontable({ rhandsontable(data = cars_rv$table, selectCallback = TRUE) %>% hot_col("mpg", colWidths = 75, readOnly = T) %>% hot_col("cyl", colWidths = 75, readOnly = T) %>% hot_col("disp", colWidths = 90, readOnly = T) %>% hot_col("hp", colWidths = 90, readOnly = T) %>% hot_col("drat", colWidths = 75, readOnly = T) %>% hot_col("wt", colWidths = 75, readOnly = T) %>% hot_col("qsec", colWidths = 90, readOnly = T) %>% hot_col("vs", colWidths = 75, readOnly = T) %>% hot_col("am", colWidths = 75, readOnly = T) %>% hot_col("gear", colWidths = 75, readOnly = T) %>% hot_col("carb", colWidths = 75, readOnly = T) }) shinyjs::disable("remove_row_button") }) observeEvent(input$sort_button, { edited_data <- hot_to_r(input$cars_table) edited_data <- edited_data[order(edited_data$tiers), ] cars_rv$table <- edited_data cars_rv$original_order <- 1:nrow(cars_rv$table) }) } )
关键修改说明
- 删除强制重设tiers的代码:移除了
mutate(tiers = row_number()),彻底避免覆盖用户自定义的层级值(包括重复的同层级设置) - 移除错误的排序逻辑:删掉了
arrange(match(tiers, cars_rv$original_order)),用户点击排序按钮后表格已按tiers排好序,删除行后只需保留剩余行的现有顺序 - 完整保留用户层级设置:删除操作后,tiers列完全保留用户之前编辑的数值,无论是连续编号还是重复层级都不会被修改
内容的提问来源于stack exchange,提问作者Harry Kalsted
相关产品推荐
相关产品推荐

