Reputation: 1492
I have a problem trying to encapsulate a linear model and waldtest
in a function. When you run the wald test it can no longer tell where the data is. This happens both when the lm
and waldtest
are in the same function and when the lm
is in a function and waldtest
is in the global (or a different function) environment.
# Loading Packages
library(lmtest)
# Loading Data
x <- sin(1:100)
y <- 1 + x + rnorm(100)
dd = data.frame(x = x, y = y)
form = "y ~ x"
When I do the regression and waldtest outside a function there is no problem:
# Doing Regression outside function
Model1 = lm(formula = form, data = dd)
waldtest(Model1)
When I do the regression and waldtest inside a function there are errors:
# Doing Regression inside function
reg = function(form, FrameOfData){
Model = lm(formula = form, data = FrameOfData)
print(waldtest(Model))
}
reg(form, FrameOfData = dd)
# Error in is.data.frame(data) : object 'FrameOfData' not found
Changing the above waldtest command to print(waldtest(Model2, data = dd))
is also unsuccessful returning # Error in modelUpdate(objects[[i - 1]], objects[[i]]) : original model was of class "lm", updated model is of class "data.frame"
The one workaround I can find is to choose a global dataframe name to match the function name (in the above case run FrameOfData = dd
before running reg
function) but I don't want to do this for the application I have in mind.
The most similar question I can find is this one: Regression with Heteroskedasticity Corrected Standard Errors where this problem does not arise as the linear regression is run in the global environment.
Is there anyway to run the lm
command and then change the object's attributes to point to the global dataframe's true name? Otherwise is there a way to tell the waldtest
command the global dataframe's true name?
Upvotes: 5
Views: 933
Reputation: 269481
1) do.call In function reg
replace the line that defines Model
with:
Model <- do.call("lm", list(formula = form, data = FrameOfData))
1a) A variation:
Model <- do.call("lm", list(formula = form, data = substitute(FrameOfData)))
2) with Alternately, this would work:
Model <- with(FrameOfData, lm(formula = form))
3) eval Yet another possibility is this:
Model <- eval(substitute(lm(formula = form, data = FrameOfData)))
although using eval
tends to be frowned upon.
3a) Here is a variation:
reg <- function(form, FrameOfData) {
eval(substitute(waldtest(lm(formula = form, FrameOfData)),
list(form = form, FrameOfData = FrameOfData)))
}
Note: There are potential problems with most of the above. The following based on (1) should work and (3a) works in this case too but the corresponding code for all the others will fail:
set.seed(123)
rm(x, y, dd, form)
fn <- function() {
x <- sin(1:100)
y <- 1 + x + rnorm(100)
dd = data.frame(x = x, y = y)
form = "y ~ x"
reg(form, FrameOfData = dd)
}
reg <- function(form, FrameOfData){
Model <- do.call("lm", list(formula = form, data = FrameOfData))
waldtest(Model)
}
fn()
Upvotes: 2