R中函数内使用公式时如何正确设置dataframe的作用域
问题根源
这个问题是R公式的环境绑定机制和survminer包surv_pvalue函数的变量查找逻辑共同导致的:
- R中创建的公式对象会默认绑定它生成时所在的环境,你在函数内部写的公式,绑定的是函数的临时执行环境,函数运行结束后这个环境默认会被回收,相关变量就找不到了
surv_pvalue计算p值时需要重新评估公式里的变量,默认优先从公式绑定的环境查找,而不是直接从survfit返回的拟合对象里提取数据,就会报变量找不到的错误
你直接在全局环境运行没问题,是因为公式绑定的是全局环境,变量一直存在不会被回收。
可行解决方案
推荐优先级从高到低:
1. 给surv_pvalue显式传入data参数(最简单无副作用)
直接把你用来拟合的data框传给surv_pvalue的data参数,它就会优先从你传的data里找变量,不需要去公式环境查找,改动最小:
library(survival) library(survminer) set.seed(1) give_p_val <- function() { df <- data.frame('OS' = ovarian[, 'futime'], 'Survival_event' = ovarian[, 'fustat']) subgroup <- sample(nrow(df), nrow(df)/2) df$Class <- 'A' df$Class[subgroup] <- 'B' fit2 <- survfit(Surv(OS, Survival_event) ~ Class, data=df) # 显式传data参数 return(surv_pvalue(fit2, data = df)) } give_p_val( )
另一个测试用例修改后也可以正常运行:
testit<-function(){ ovarian2 <- ovarian fit2 <- survfit(Surv(futime, fustat) ~ rx, data=ovarian2) return(surv_pvalue(fit2, data = ovarian2)) } testit()
2. 创建公式时显式指定绑定环境
如果不想每次都传data参数,可以在创建公式时手动指定绑定的环境,确保变量查找路径正确:
give_p_val <- function() { df <- data.frame('OS' = ovarian[, 'futime'], 'Survival_event' = ovarian[, 'fustat']) subgroup <- sample(nrow(df), nrow(df)/2) df$Class <- 'A' df$Class[subgroup] <- 'B' # 显式指定公式绑定当前函数环境 form <- as.formula(Surv(OS, Survival_event) ~ Class, env = environment()) fit2 <- survfit(form, data=df) return(surv_pvalue(fit2)) }
不推荐的方案
不要用<<-或者assign把函数内部的data框写到全局环境,这种做法会污染全局命名空间,多线程运行或者多函数调用时很容易出现变量冲突,导致不可预期的错误。
内容的提问来源于stack exchange,提问作者OatMeal
相关产品推荐
相关产品推荐

