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返回的是字符串类型,直接传递会触发类型不匹配的错误。
修改步骤
- 将字符串类型的分组变量转换为符号:用
rlang::sym()函数把input$group_var的字符串值转为gtsummary可识别的符号。 - 移除
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
相关产品推荐
相关产品推荐

