error object not found when calling with(dataset, coxph(formula))

1.7k Views Asked by At

I have a multiply imputed dataset of class mids. I use the with() function to estimate the m different datasets with the coxph() function. However, I'm having trouble using the with() function within my own function.

The code below is a simplified example that reproduces the error: Error in Surv(enter,exit,event) object 'enter' not found

list<-"X1+X2"
var.used<-formula(paste("Surv(enter,exit,event)~",list,sep=""))

with.coxph<-function(form,dataset){
 with(dataset,coxph(form))
}

with.coxph(var.used,data)

When I simply run the function on its own:

with(dataset, coxph(Surv(enter,exit,event)~X1+X2))

It works fine.

I think the problem is related to the environment where with() is called. I found different posts in here, but I can't seem to make it work. I tried assigning the dataset and the formula to the global environment:

with.coxph2<-function(form,dataset){
 assign(".dataset",dataset,envir=.GlobalEnv)
 assign(".form",dataset,envir=.GlobalEnv)
 with(dataset,coxph(form))
 remove(".dataset",dataset,envir=.GlobalEnv)
 remove(".form",dataset,envir=.GlobalEnv)
}

with.coxph2(var.used,data)

but this produced the same error.

EDIT

I have attempted to fix the problem as described below. When i simply run the function with out the with() statement it works perfectly.

makeModel<-function(resp, explan, mData) {
 mF <- formula(paste(resp, paste(explan, collapse = "+"), sep = "~"))
 mod <- coxph(mF, data = mData)
 mod$call$formula <- mF
 mod$call$data <- as.symbol(deparse(substitute(mData)))
 mod
}

cp <- makeModel("Surv(start, stop, event)", "X1", complete(data))

# This works fine

However, I still get the same error when I include the with() statement in the equation:

with.coxph<-function(resp, explan, mData) {
 mF <- formula(paste(resp, paste(explan, collapse = "+"), sep = "~"))
 mod <- with(mData,coxph(mF))
 mod$call$formula <- mF
 mod$call$data <- as.symbol(deparse(substitute(mData)))
 mod
}

cp <- with.coxph("Surv(start, stop, event)", "X1", data)

# Error in Surv(enter,exit,event): object 'enter' not found

2

There are 2 best solutions below

3
On

I had similiar issues when using the lm function and I wanted to pass the formula and/or data argument to it. Tha's what I am doing now to circumvent that:

makeModel <- function(resp, explan, mData) {
   mF <- formula(paste(resp, paste(explan, collapse = "+"), sep = "~"))
   mod <- coxph(mF, data = mData)
   mod$call$formula <- mF
   mod$call$data <- as.symbol(deparse(substitute(mData)))
   mod
}

makeModelBad <- function(resp, explan, mData) {
   mF <- formula(paste(resp, paste(explan, collapse = "+"), sep = "~"))
   coxph(mF, data = mData)
}

library(survival)
example(coxph) # to load the data

(cp <- makeModel("Surv(start, stop, event)", "x", test2))
# Call:
# coxph(formula = Surv(start, stop, event) ~ x, data = test2)
#
#
#      coef exp(coef) se(coef)       z    p
# x -0.0211     0.979    0.795 -0.0265 0.98
#
# Likelihood ratio test=0  on 1 df, p=0.979  n= 10, number of events= 7 

cp.bad <- makeModelBad("Surv(start, stop, event)", "x", test2)

Explanation

In order to use the models created inside a function, I had to explicitely change the respective slots, because mData is not known outside the function and a call to update for example will fail:

update(cp, . ~ 1) # works
update(cp.bad, . ~ 1) # does not work
# Error in terms.formula(formula, special, data = data) : 
# object 'mData' not found 

The change to the formula slot, is more eye candy to show the formula in the print of the object.

0
On

If anyone else should ever be lucky enough to stumble onto this wonderful problem: A solution to this problem can be deduced from this question. Apparently when working with the with function, the formula has to be parsed into a formula only within the with function, i.e., if you have a formula string (or character to stick with R terminology), keep it as a string for now to use as.formula() or formula() later in the function.

Example:

formula.cox <- as.formula(sprintf("Surv(time_months, some_boolean) ~ %s", paste(names(c.cox), collapse = " + ")))
cox <- with(df.cox.mice, coxph(formula = formula.cox)) # throws error: object 'time_months' not found

formula.cox <- sprintf("Surv(time, some_boolean) ~ %s", paste(names(c.cox), collapse = " + "))
cox <- with(df.cox.mice, coxph(formula = as.formula(formula.cox))) # no errors