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

如何将数据框列名传入含survival::Surv的自定义函数?

解决coxph自定义函数中列名参数解析问题

错误原因

你遇到的Error in Surv(tte, eventfl) : object 'pfstte' not found,本质是coxph的公式解析环境问题:公式默认在全局环境查找变量,而你的tte和eventfl是函数参数,代表indf的列名,直接写Surv(tte, eventfl)会被当成全局对象,而非数据框的列。

修正后的函数(两种可行方案)

方案1:用tidy eval动态构建公式

利用rlang包的表达式工具,将参数解析为列名后构建公式:

hrdf <- function(indf, tte, eventfl) {
  # 构建Surv表达式,用{{}}解析列名参数
  surv_expr <- rlang::expr(Surv({{tte}}, {{eventfl}}))
  # 组合成完整的coxph公式
  cox_formula <- rlang::new_formula(surv_expr, rlang::expr(ENRLARM_STD))
  
  df <- broom::tidy(coxph(cox_formula, data = indf[indf$SEX == 'Female',], ties = 'efron'), conf.int = TRUE) %>%
    dplyr::mutate(term = 'Sex', cat = 'Female')
  return(df)
}

方案2:用符号转换拼接公式字符串

这种方式更直观,适合习惯字符串操作的场景:

hrdf <- function(indf, tte, eventfl) {
  # 将函数参数转换为列名符号
  tte_col <- rlang::ensym(tte)
  event_col <- rlang::ensym(eventfl)
  
  # 拼接成公式字符串并转换为公式对象
  cox_formula <- as.formula(paste0("Surv(", as.character(tte_col), ", ", as.character(event_col), ") ~ ENRLARM_STD"))
  
  df <- broom::tidy(coxph(cox_formula, data = indf[indf$SEX == 'Female',], ties = 'efron'), conf.int = TRUE) %>%
    dplyr::mutate(term = 'Sex', cat = 'Female')
  return(df)
}

调用方式

直接传入列名(无需加引号)即可:

# 示例:假设数据框为mydata,时间列是pfstte,事件列是pfsevent
hrdf(mydata, pfstte, pfsevent)

为什么之前的尝试无效?

  • {{}}:单独放在Surv(tte, eventfl)里不生效,因为{{}}的解析逻辑主要适配dplyr等tidyverse函数,直接在公式的Surv调用中无法被正确识别;
  • [[]]:如果直接写成Surv(indf[[tte]], indf[[eventfl]]),coxph的公式不接受这种直接传入对象的写法,必须是基于数据框列名的引用;
  • eval()/substitute():如果没结合公式的完整构建(比如只替换了参数但没生成合法的公式对象),会因为环境不匹配导致解析失败。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 16:43:14