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

如何在Shiny中编辑列后更新可编辑数据表并执行连续计算

解决Shiny中可编辑数据表依赖列更新问题

问题分析

你需要让DT表格中可编辑的ppl列变化后,自动更新所有依赖该列、侧边栏输入的计算列。核心是要把数据表变成可响应更新的状态,并监听编辑事件来修改数据,再触发计算逻辑重新运行。

关键修改步骤

  • 使用reactiveVal存储数据表,这样数据变化时能自动通知依赖它的组件。
  • 通过observeEvent监听DT的单元格编辑事件(input$table1_cell_edit),更新ppl列的对应值。
  • 计算逻辑基于reactiveVal中的数据和侧边栏输入,确保任何变化都会触发重新计算。

修改后完整代码

library(tidyverse)
library(shiny)
library(DT)

ui <- 
  sidebarLayout(
    sidebarPanel(
      numericInput("price", label = "单价 ($)", value = 4.31, min = 0),
      numericInput("sqft", label = "平均平方英尺数", value = 4400, min = 0),
      numericInput("delivery", label = "配送成本", value = 2.60, min = 0),
      numericInput("avg_use", label = "年平均使用量", value = 88000, min = 0),
      numericInput("turf", label = "百分比 (%)", value = 0, min = 0)
    ),
    mainPanel(
      DTOutput("table1")
    )
  )


server <- function(input, output, session) {
  
  # 初始化可响应更新的数据表
  raw_df <- reactiveVal(
    data.frame(
      behavior = c("A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K"),
      average = c(2541, 11913, 12707, 16995, 23668, 2859, 2224, 10483, 22555, 8259, 5718),
      ppl = rep(72, 11)
    )
  )
  
  # 监听DT表格的编辑事件,更新ppl列
  observeEvent(input$table1_cell_edit, {
    info <- input$table1_cell_edit
    current_df <- raw_df()
    # DT列索引从0开始,ppl列是第2位
    if (info$col == 2) { 
      current_df[info$row, "ppl"] <- as.numeric(info$value)
      raw_df(current_df)
    }
  })
  
  # 生成包含计算列的最终数据表
  calculated_df <- reactive({
    raw_df() %>%
      mutate(
        total_land = ifelse(str_detect(behavior, "E") & input$turf > 0,
                           ppl * input$sqft * input$turf,
                           ppl * input$sqft),
        all_w = average * (total_land / 1000),
        all_ut = input$price * (all_w / 1000),
        annual_w = all_w / ppl,
        mon_w = annual_w / 12,
        annual_ut = all_ut / ppl,
        mon_ut = annual_ut / 12,
        deliv = (all_w / 1000) * input$delivery,
        supply = all_w / input$avg_use
      )
  })
  
  output$table1 <- renderDT(
    calculated_df(),
    selection = 'none',
    editable = list(target = 'column', disable = list(columns = c(0:1, 3:12))),
    server = TRUE,
    rownames = FALSE
  )
}

shinyApp(ui, server)

代码说明

  1. reactiveVal的作用:raw_df是一个响应式的值,存储原始的可编辑数据,当它被修改时,所有依赖它的组件(比如calculated_df)都会自动重新计算。
  2. 编辑事件监听:observeEvent捕获用户对表格的编辑操作,只允许修改ppl列,并更新raw_df中的对应值。
  3. 计算逻辑分离:把原始数据和计算列分开,calculated_df基于raw_df和侧边栏输入生成最终表格,确保任何输入变化(包括ppl列的编辑)都会触发所有计算列更新。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 15:47:49