使用purrr实现多分层Cox回归通用函数时的变量未找到错误排查求助
嗨,我帮你排查下这个问题,你的代码里有两个关键的小问题,导致了follow_up_time变量找不到和协变量处理失效的问题,咱们一步步来解决:
问题1:follow_up_time的变量查找环境错误
你在Surv({{follow_up_time}}, death_all_cause)中用了{{}}来引用参数,但当你用nest()拆分数据后,map闭包内的{{follow_up_time}}会优先在函数的外层环境查找,而不是当前分层的子数据框(.x)中匹配列,这就触发了“变量未找到”的错误。
问题2:协变量的公式构建逻辑错误
你传入的covariates是字符串向量(比如c("covariate1", "covariate2")),但coxph公式里直接写~ covariates的话,R会误以为你要找一个叫covariates的变量,而不是把这两个字符串作为协变量项加入模型。
修复后的完整函数
结合这两个问题的修复,调整后的函数如下:
library(tidyverse) library(survival) library(broom) library(rlang) run_cox_reg <- function(dataframe, strata = NULL, follow_up_time, covariates) { # 把传入的裸变量名转成R符号对象,确保后续能正确解析 follow_up_time_sym <- ensym(follow_up_time) # 把字符串协变量转成符号列表,方便拼接公式 covar_syms <- syms(covariates) result <- dataframe |> # 先剔除分层变量的缺失值,避免空分层组 drop_na({{strata}}) |> group_by({{strata}}) |> nest() |> mutate(test_results = map(.x = data, .f = ~ { # 动态构建Cox回归公式 cox_formula <- new_formula( lhs = call2("Surv", !!follow_up_time_sym, quote(death_all_cause)), rhs = expr(!!!covar_syms) ) # 运行回归并整理结果 coxph(cox_formula, data = .x) |> broom::tidy(conf.int = TRUE, exponentiate = TRUE) } )) |> unnest(test_results) |> select(strata, term, estimate, std.error, conf.low, conf.high) |> ungroup() return(result) }
关键修改说明
follow_up_time的正确引用:
用ensym(follow_up_time)把传入的裸变量名(比如follow_up_time_variable)转成符号对象,后续用!!解引用时,能准确指向子数据框中的对应列,不会再出现“变量未找到”的问题。协变量的公式动态构建:
用syms(covariates)把字符串协变量转成符号列表,再通过!!!拼接成公式的右侧项,这样coxph就能正确识别你传入的多个协变量。缺失值处理优化:
把drop_na({{strata}})移到group_by之前,提前剔除无效的分层组,减少不必要的计算。
测试调用示例
只要你的数据框name_of_df包含strata_variable、follow_up_time_variable、covariate1、covariate2和death_all_cause列,现在可以正常调用:
run_cox_reg( dataframe = name_of_df, strata = strata_variable, covariates = c("covariate1", "covariate2"), follow_up_time = follow_up_time_variable )
这样应该就能顺利运行啦~
备注:内容来源于stack exchange,提问作者Simen Løkken

