如何安全地使用 coxph 和子集或权重? [英] How do I use safely with coxph and subset or weights?
问题描述
我正在尝试将 purrr::safely 与 coxph 一起使用,以便我可以捕获错误消息.我制作了一个安全版本的 coxph 如下
I'm trying to use purrr::safely with coxph so that I can capture error messages. I've made a safe version of coxph as follows
library(survival)
library(purrr)
coxph_safe <- safely(coxph)
当我的唯一输入是公式和数据时,这非常有效,但是,如果我添加另一个输入(例如子集或权重),则会收到以下错误消息:
This works perfectly when my only inputs are the formula and data, however, if I add another input such as subset or weights, I get the following error message:
eval(substitute(subset), data, env) 中的 simpleError: ..3 在不正确的上下文中使用,没有......查看
simpleError in eval(substitute(subset), data, env): ..3 used in an incorrect context, no ... to look in
有谁知道在需要额外输入时如何安全地应用于 coxph?我也会得到同样的错误,而不是安全地使用,并且如果我制作了一个安全版本的 lm 并指定了一个子集.我正在使用 R 3.6.1 和 purrr 0.3.2.目前,我已经编写了一个变通方法,即在应用 coxph_safe 之前对数据进行子集化,但最好知道是否有更好的解决方案.
Does anyone know how to apply safely to coxph when additional inputs are required? I also get the same error using quietly instead of safely, and also if I make a safe version of lm and specify a subset. I'm using R 3.6.1 and purrr 0.3.2. For now, I've programmed a workaround, where I subset the data before applying coxph_safe, but it would be good to know if there was a better solution.
这是一个简单的例子:
test1 <- list(time=c(4,3,1,1,2,2,3),
status=c(1,1,1,0,1,1,0),
x=c(0,2,1,1,1,0,0),
sex=c(0,0,0,0,1,1,1))
# Without subset
coxph(Surv(time, status) ~ x, test1) # Works as expected
coxph_safe(Surv(time, status) ~ x, test1) # Works as expected
# With subset
coxph(Surv(time, status) ~ x, test1, subset = !sex) # Works as expected
coxph_safe(Surv(time, status) ~ x, test1, subset = !sex) # Error!
编辑
在相关说明中,将方差分析应用于通过 coxph_safe 生成的 coxph 对象时,我也遇到了类似的错误.
On a related note, I also get a similar error when applying anova to a coxph object generated via coxph_safe.
cox_1 <- coxph(Surv(time, status) ~ x, test1) # Works as expected
anova(cox_1) # Works as expected
cox_1s <- coxph_safe(Surv(time, status) ~ x, test1) # Works as expected
anova(cox_1s$result) # Error in is.data.frame(data) : ..2 used in an incorrect context, no ... to look in
据我所知,这与呼叫的存储方式有关.我可以通过覆盖调用来修复它.
As far as I can tell, this has something to do with how the call is stored. I can fix it by over-writing the call.
cox_1$call # coxph(formula = Surv(time, status) ~ x, data = test1)
cox_1s$result$call # .f(formula = ..1, data = ..2)
cox_1s$result$call <- cox_1$call
anova(cox_1s$result) # Now works as expected
有没有更好的方法来解决这个问题?
Is there a better way around this?
推荐答案
这实际上与 purrr::safely
无关.问题是函数嵌套.考虑:
This actually has nothing to do with purrr::safely
. The issue is function nesting. Consider:
f <- function(...) {coxph(...)}
f(Surv(time, status) ~ x, test1) # Works
f(Surv(time, status) ~ x, test1, subset=!sex) # Error
失败的真正原因与有关substitute()
在嵌套函数中的行为.coxph()
使用 substitute()
,并且 safely()
创建了一个嵌套函数,导致了我链接中描述的场景.
The real reason for why it fails has to do with the behavior of substitute()
inside nested functions. coxph()
uses substitute()
, and safely()
creates a nested function, leading to the scenario described in my link.
为了解决这个问题,我们需要将 coxph()
包装成一个正确处理非标准评估 (NSE) 的函数:
To address this issue, we need to wrap coxph()
into a function that properly handles non-standard evaluation (NSE):
coxph_nse <- function(...) {eval(rlang::expr(coxph( !!!rlang::enexprs(...) )))}
新函数不再遇到相同的嵌套问题,可以安全地传递给safely()
:
The new function no longer suffers the same nesting issues and can be safely passed to safely()
:
coxph_safe <- safely(coxph_nse)
coxph_safe(Surv(time, status) ~ x, test1) # works
cx1 <- coxph_safe(Surv(time, status) ~ x, test1, subset=!sex) # now also works!
anova(cx1$result) # works as well!
这篇关于如何安全地使用 coxph 和子集或权重?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!