使用pryr或其他tidyverse工具修复survival()环境“is.data.frame中的错误”错误

时间:2018-02-16 20:49:37

标签: r environment-variables pryr

我正在努力为环境问题找到一个优雅的解决方案,我不断使用R中的生存库。这是我遇到的问题的玩具示例:

# Make a fake data set
set.seed(1)
BigData <- cbind(rexp(100, .3), rbinom(100, 1, .7), 
             matrix(rnorm(300), ncol = 3)) %>% data.frame
names(BigData) <- c('time','event', 'var1', 'var2', 'var3')

# Make n function for fitting the model (myFitFunction).
# I am allowed to edit this function.
myFitFunction <- function(origdata, formula, ...){
  fit <- coxph(formula, data = origdata, ...)
  return(fit)
}
# There exists a function for fitting the 
# same model with new data (otherFitFunction).
# For the purposes of this example, say I cannot edit this one.
otherFitFunction <- function(object, newdata){
  survfit(object, newdata=newdata)
}
myMod <- myFitFunction(BigData[1:75,], 
        as.formula(Surv(time, event) ~ var1+var2+var3))
otherFitFunction(myMod, BigData[76:100,])

这给了我错误信息:

“is.data.frame(data)中的错误:找不到对象'origdata' 电话:otherFitFunction ... - &gt; model.frame.default - &gt; is.data.frame“

我知道这是一个常见问题,特别是在进行交叉验证时,有一些解决方案,例如: in R: Error in is.data.frame(data) : object '' not found, C5.0 plot。 (更具体地说,我知道这个例子中的问题来自于生存包中“survfit.coxph.R”文件中第55行的stats :: model.frame()代码。)通过阅读stackexchange上的其他帖子,我找到了我的问题的 解决方案,即将myFitFunction()调整为:

myFitFunction <- function(origdata, formula, ...){
  myenv$origdata <- origdata
  fit <- coxph(formula, data = origdata, ...)
  environment(fit$formula) <- myenv
  fit$terms <- terms(fit$formula)

  return(fit)
}

然而,我见过或使用的所有代码看起来都非常hacky(包括我的,这需要我每次都保存origdata)。另外,在我的真实代码中,我实际上无法编辑otherFitFunction()并且只能编辑甚至直接访问myFitFunction(),这限制了我使用其他人使用的一些解决方案的能力。

我想知道这个问题是否有更优雅的解决方案。我试过玩pryr包但似乎无法想出任何有用的东西。

非常感谢任何帮助。

1 个答案:

答案 0 :(得分:1)

怎么样

myFitFunction <- function(origdata, formula, ...){
  environment(formula) <- environment()
  fit <- coxph(formula, data = origdata, ...)
  return(fit)
}

由于公式可以捕获环境,因此您只需要捕获定义origdata的环境。

另一种方法是调整myFitFunction中的调用,以使用原始变量运行父框架中的所有内容。例如

myFitFunction <- function(origdata, formula, ...){
  call <- match.call()
  call$formula <- formula
  call$data <- call$origdata
  call$origdata <- NULL
  call[[1]] <- quote(coxph)
  fit <- eval.parent(call)
  return(fit)
}