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

Shiny中用gtsummary生成分组生存表时遇'symbol不可子集化'错误

问题描述

构建Shiny应用生成指定时间点的生存百分比表,支持分组对比(如性别、药物组)。无分组的生存表可正常运行,但添加分组变量后,运行报错:"object of type 'symbol' is not subsettable"。调试确认survfit模型拟合正常,问题出在gtsummary的tbl_ard_summary构建环节。

问题核心代码片段:

tbl_survival <- 
  fit |> 
  cardx::ard_survival_survfit(times = input$timepoint) |> 
  cards::update_ard_fmt_fn(
    stat_names = c("estimate", "conf.low", "conf.high"),
    fmt_fn = label_style_sigfig(digits = 2, scale = 100)
  ) |> 
  dplyr::mutate(context = "categorical") |> 
  tbl_ard_summary(
    by = if (input$group_var == "None") NULL else input$group_var, # 此处直接传字符串触发错误
    label = list(time = paste0(input$timepoint, " months Survival Probability")),
    statistic = time ~ "{estimate}% (95% CI {conf.low}%, {conf.high}%)"
  )
解决方案

问题根源

tbl_ard_summary的by参数要求传入符号(symbol)(如gender)而非字符串(如"gender"),但Shiny中input$group_var返回的是字符串类型,直接传递会触发类型不匹配的错误。

修改步骤

  1. 将字符串类型的分组变量转换为符号:用rlang::sym()函数把input$group_var的字符串值转为gtsummary可识别的符号。
  2. 移除dplyr::mutate(context = "categorical"):该手动修改上下文的操作会干扰gtsummary对生存分析结果的自动解析,无需保留。

修改后的完整Server代码

server <- function(input, output, session) {
  
  output$surv_table <- render_gt({
    # Validate inputs
    req(input$time_var, input$status_var, input$timepoint)
    
    # Create the survival object
    surv_obj <- Surv(time = data[[input$time_var]], event = data[[input$status_var]])
    
    # Determine grouping formula
    if (input$group_var == "None") {
      formula <- surv_obj ~ 1
    } else {
      formula <- as.formula(paste("surv_obj ~", input$group_var))
    }
    
    # Fit the survival model
    fit <- survfit(formula, data = data)
    
    # Build tbl_survival using the input value
    tbl_survival <- 
      fit |> 
      cardx::ard_survival_survfit(times = input$timepoint) |> 
      cards::update_ard_fmt_fn(
        stat_names = c("estimate", "conf.low", "conf.high"),
        fmt_fn = label_style_sigfig(digits = 2, scale = 100)
      ) |> 
      tbl_ard_summary(
        # 关键修改:将字符串转换为符号
        by = if (input$group_var == "None") NULL else rlang::sym(input$group_var),
        label = list(time = paste0(input$timepoint, " months Survival Probability")),
        statistic = time ~ "{estimate}% (95% CI {conf.low}%, {conf.high}%)"
      )
    
    # Convert to gt table before rendering
    gt_table <- as_gt(tbl_survival)
    
    # Render the table
    gt_table
  })
}

替代方案(不依赖rlang包)

使用.data代词直接引用列名:

by = if (input$group_var == "None") NULL else .data[[input$group_var]]

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 06:57:02