I am writing a function in R that will evaluate the fit of a model, but each model takes the same arguments. How can I avoid repeating the same argument to each call to a model?
It is probably more clear here, where the arguments
data=data,
na.action = na.exclude,
subset = block == site)
Are repeated.
modelfit <- function(order, response, predictor, site) {
if(order == 0) {
m <- lm(response ~ 1,
data=data,
na.action = na.exclude,
subset = block == site)
} else if (is.numeric(order)) {
开发者_JS百科 m <- lm(response ~ poly(predictor, order),
data=data,
na.action = na.exclude,
subset = block == site)
} else if (order == 'monod') {
x<-predictor
m <- nls(response ~ a*x/(b+x),
start = list(a=1, b=1),
data=data,
na.action = na.exclude,
subset = block == site)
} else if (order == 'log') {
m <- lm(response ~ poly(log(predictor), 1),
data=data,
na.action = na.exclude,
subset = block == site)
}
AIC(m)
}
Additional suggestions for better approaches to this question always appreciated.
You can use the ...
idiom to do this. You include ...
in the argument definition of your function and then within the lm()
calls include ...
as an extra argument. The ...
effectively is a placeholder for all the extra arguments you wish to pass. Here is a (not tested) modification of your function that employs this approach:
modelfit <- function(order, response, predictor, site, ...) {
if(order == 0) {
m <- lm(response ~ 1, ...)
} else if (is.numeric(order)) {
m <- lm(response ~ poly(predictor, order), ...)
} else if (order == 'monod') {
x<-predictor
m <- nls(response ~ a*x/(b+x), start = list(a=1, b=1), ...)
} else if (order == 'log') {
m <- lm(response ~ poly(log(predictor), 1), ...)
}
AIC(m)
}
You then call this function and provide the repeated arguments in place of ...
:
with(myData, modelfit(2, myResponse, myPredictor, mySite, data = myData,
na.action = na.exclude, subset = block == mySite))
where myResponse
, myPredictor
and mySite
are the variables you want to use that exist in your myData
data frame.
I would like to clarify a point in Gavin's answer with a simplified example:
Here is a dataframe d
:
d <- data.frame(x1 = c(1, 1, 1, 1, 2, 2, 2, 2),
x2 = c(1, 1, 1, 2, 1, 1, 1, 2),
y = c(1, 1, 3, 4, 5, 6, 7, 8))
Here is a function:
mf <- function(response, predictor, ...) {
lm(response~predictor, ...)
}
Note that
mf(d$y, d$x1, subset = d$x2 == 1, data = d)
works, but
mf(y, x1, subset = x2 == 1, data = d)
does not.
精彩评论