Search code examples
rformulastatistics-bootstrap

R saving function call with formula for reuse in bootstrapping


I've got some code that creates an object from a formula and saves the call for future use, as so:

create_obj <- function(formula, data) {
    obj <- list()
    # Populate obj with whatever we're interested in
    # ...        

    # Save call for future use
    obj$call <- match.call()
    obj
}

obj <- create_obj(time ~ sex, data)

If I then bootstrap data I can easily build the model on the new dataset:

data <- data[sample(1:nrow(data), replace=T), ]
new_obj <- eval(obj$call)

However, if I have the formula saved in a variable and I pass the object into a new environment this won't work:

do_stuff <- function(object, newdata) {
    data <- newdata[sample(1:nrow(newdata), replace=T), ]
    new_object <- eval(object$call)
}

main <- function() {
    my_form <- time ~ sex
    obj2 <- create_obj(my_form, data)
    # obj2$call: 'create_obj(formula = my_form, data = data)'

    do_stuff(obj2, data)

}

Error: object my_form not found.

How can I have it so that obj$call saves time~sex rather than myform? Otherwise I need to pass the formula itself around rather than just the object, limiting the practicality.

The above example isn't reproducible but you can see the same thing with a standard lm call.

EDIT: I've solved the problem, see the accepted answer.


Solution

  • I've solved it by having the constructor function modify the call by evaluating the constant argument in the local environment:

    create_obj <- function(formula, data) {
        obj <- list()
        # Populate obj with whatever we're interested in
        # ...        
    
        # Save call for future use
        func_call <- match.call()
        func_call$formula <- eval(formula)
    
        # obj_call is now: create_obj(formula=time~sex, data=data)
        obj$call <- func_call
        obj
    }