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

在Shiny表格每行添加selectInput并单独计算选项切换时长

解决方案:替换actionButton为selectInput并实现每行单独计时

我来帮你搞定这个需求!我们需要把表格里的按钮换成带三个选项的下拉框,同时为每行单独跟踪状态切换的时间,这样就能精准记录从选项2切换到3的时长并写入对应的Time列。下面是修正后的完整代码,我会逐段解释关键改动:

library(shiny)
library(DT)

ui <- fluidPage(
  navbarPage(
    "My App",
    mainPanel(
      DT::dataTableOutput("data"),
      textOutput('myText')
    )
  )
)

server <- function(input, output, session) {
  myValue <- reactiveValues(Action = '')
  
  # 生成每行的selectInput组件
  shinyInput <- function(FUN, len, id, ...) {
    inputs <- character(len)
    for (i in seq_len(len)) {
      # 创建带三个选项的下拉框,默认选中第一个选项
      inputs[i] <- as.character(FUN(paste0(id, i), 
                                   choices = c("选项1", "选项2", "选项3"),
                                   selected = "选项1",
                                   label = NULL))
    }
    inputs
  }
  
  # 初始化数据表,将Actions列替换为selectInput
  seriet <- reactiveValues(
    data = data.frame(
      Name = c('Laurena', 'Jennifer', 'Augusto', 'Henrique', 'Zeina','Jaque'),
      Grade = c(1, 2, 3, 2, 1, 3),
      Time = rep(0, 6),
      Sport = c("Nado", "Corrida","Nado", "Corrida","Nado", "Corrida"),
      Actions = shinyInput(selectInput, 6, 'select_'),
      stringsAsFactors = FALSE,
      row.names = 1:6
    )
  )
  
  # 为每行维护独立的状态记录:上一次选中值、切换到选项2的时间戳
  rowStatus <- reactiveValues()
  for(i in 1:nrow(seriet$data)){
    rowStatus[[paste0("prev_val_", i)]] <- "选项1"
    rowStatus[[paste0("timer_start_", i)]] <- NULL
  }
  
  # 渲染可交互表格
  output$data <- DT::renderDataTable(
    seriet$data,
    escape = FALSE,
    selection = "none"
  )
  
  # 为每行的selectInput创建独立的监听逻辑
  lapply(1:nrow(seriet$data), function(i){
    observeEvent(input[[paste0("select_", i)]], {
      current_val <- input[[paste0("select_", i)]]
      prev_val <- rowStatus[[paste0("prev_val_", i)]]
      
      # 检测从选项2切换到选项3的动作,计算时长并更新Time列
      if(prev_val == "选项2" && current_val == "选项3"){
        if(!is.null(rowStatus[[paste0("timer_start_", i)]])){
          duration_sec <- as.numeric(Sys.time() - rowStatus[[paste0("timer_start_", i)]], units = "secs")
          seriet$data$Time[i] <- round(duration_sec, 2)
          myValue$Action <- paste("第", i, "行:从选项2到3耗时", round(duration_sec, 2), "秒")
        }
      }
      
      # 切换到选项2时,记录当前时间戳
      if(current_val == "选项2"){
        rowStatus[[paste0("timer_start_", i)]] <- Sys.time()
      }
      
      # 更新当前行的上一次选中值
      rowStatus[[paste0("prev_val_", i)]] <- current_val
    })
  })
  
  output$myText <- renderText({
    myValue$Action
  })
}

shinyApp(ui, server)

关键改动说明:

  • 替换按钮为下拉框:修改shinyInput函数,生成带三个选项的selectInput,每个组件有独立ID对应表格行。
  • 每行独立状态跟踪:用rowStatus这个reactiveValues存储每行的上一次选中值和切换到选项2的时间戳,彻底解决全局统计的问题。
  • 精准计算时长:监听每行下拉框的变化,当检测到从选项2切换到3时,计算时间差并直接更新对应行的Time列,表格会自动刷新显示结果。

这样就能完美解决你遇到的两个问题:不仅能把时长写入Time列,还能实现每行单独统计从选项2到3的耗时啦!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 06:40:10