You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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)
    })
  }
)

关键修改说明

  1. 删除强制重设tiers的代码:移除了mutate(tiers = row_number()),彻底避免覆盖用户自定义的层级值(包括重复的同层级设置)
  2. 移除错误的排序逻辑:删掉了arrange(match(tiers, cars_rv$original_order)),用户点击排序按钮后表格已按tiers排好序,删除行后只需保留剩余行的现有顺序
  3. 完整保留用户层级设置:删除操作后,tiers列完全保留用户之前编辑的数值,无论是连续编号还是重复层级都不会被修改

内容的提问来源于stack exchange,提问作者Harry Kalsted

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 02:39:52