在 coxph 中抑制特定警告会导致 cox.zph 错误

Suppressing specific warning in coxph leads to error with cox.zph

我想取消在 coxph 分析中经常出现的警告。众所周知,警告 "Loglik converged before variable 1 ; coefficient may be infinite" 过于敏感,我还有其他方法来检查结果。我的第一次尝试是将 coxph 包装在调用处理程序中:

coxMW <- function(...){
  withCallingHandlers(coxph(...),
                      warning=function(w) {
                        if (grepl("coefficient may be infinite", w$message))
                          invokeRestart("muffleWarning")
                      })
}

给出了预期的答案

library(survival)
coxObj1 <- coxph(Surv(futime, fustat) ~ rx, data=ovarian)
coxObj2 <- coxMW(Surv(futime, fustat) ~ rx, data=ovarian)
summary(coxObj1)
summary(coxObj2))

但是,当我尝试在 cox.zph 中使用结果时:

zph1 <- cox.zph(coxObj1)
zph2 <- cox.zph(coxObj2)

第二种情况,使用新函数,结果为:"Error in is.data.frame(data) : ..2 used in an incorrect context, no ... to look in"

我现在正在努力寻找一种方法来抑制这个特定的警告。我在一个大函数中多次使用 coxph,并且真的不想将对 coxph 的每次调用都包装在 withCallingHandlers 中。使用带有错误处理程序的 tryCatch 调用整个函数以记录错误等,然后继续下一个案例,它工作正常。但是,如果我向 tryCatch 添加一个警告处理程序,仅抑制此警告,则会退出该函数,并且我无法弄清楚如何从函数中发生警告的位置继续。我在警告处理程序中尝试了各种重启命令组合,但我真的不知道我在做什么,想知道是否有更好的方法?欢迎提出任何建议!

这是一个棘手的问题。在包装器中生成的模型不起作用的原因是 coxph 对象保留了生成它的调用记录,cox.zph 本身会重复使用该记录。当您在包装器中使用 ... 时,这些将存储为调用的参数而无需替换。当这个调用传递给cox.zph时,它不知道如何处理...参数。

您可以通过查看两个模型中存储的 call 对象来了解这一点:

coxObj1$call
#> coxph(formula = Surv(futime, fustat) ~ rx, data = ovarian)
coxObj2$call
#> coxph(formula = ..1, data = ..2)

因此,您的包装器需要将 ... 替换为模型的 call 插槽:

coxMW <- function(...){
  withCallingHandlers(result <- coxph(...),
                      warning=function(w) {
                        if (grepl("coefficient may be infinite", w$message))
                          invokeRestart("muffleWarning")
                      })

  cox_call      <- match.call()   # Contains the substituted parameters we want
  cox_call[[1]] <- quote(coxph)   # Change the wrapper's name to coxph in the call

  if(names(cox_call)[2] == "") names(cox_call)[2] <- "formula"
  result$call <- cox_call
  return(result)
}

所以现在你可以做:

coxObj2 <- coxMW(Surv(futime, fustat) ~ rx, data=ovarian)
zph2    <- cox.zph(coxObj2)
zph2
#>        chisq df   p
#> rx      2.68  1 0.1
#> GLOBAL  2.68  1 0.1