#' Variable selection for linear models by backward selection. Original code at: http://stackoverflow.com/questions/19226816/how-can-i-view-the-source-code-for-a-function. Some changes have been done.
#'
#' @param model a linear model (an object of class "lm") with the full model.
#' @param keep a list of model terms to keep in the model at all times.
#' @param sig significant level for removal of a variable.
#' @param method method for variable removal.
#' @param k a numeric value for penalizing number of variables with information criteria. Default value es 2, corresponding to Akaike Information Criteria.
#' @param verbose logical. Should R report information (dropped variable and resulting model) on progress? Default value is FALSE.
#' @param ... further arguments to be passed to or from methods.
#' @return Proposed final model.
#' @export
lm.var.select <- function(model, keep, method = c("none", "Chisq", "F"), k = 2, sig=0.05, verbose=F, ...){
counter=1
# check input
if(!is(model,"lm")) stop(paste(deparse(substitute(model)),"is not an lm object\n"))
# calculate scope for drop1 function
terms <- attr(model$terms,"term.labels")
if(missing(keep)){ # set scopevars to all terms
scopevars <- terms
} else{ # select the scopevars if keep is used
index <- match(keep,terms)
# check if all is specified correctly
if(sum(is.na(index))>0){
novar <- keep[is.na(index)]
warning(paste(
c(novar,"cannot be found in the model",
"\nThese terms are ignored in the model selection."),
collapse=" "))
index <- as.vector(na.omit(index))
}
scopevars <- terms[-index]
}
# Backward model selection :
while(T){
# extract the test statistics from drop.
test <- drop1(model, scope=scopevars, test = method, k = k)
if(verbose){
cat("-------------STEP ",counter,"-------------\n",
"The drop statistics : \n")
print(test)
}
pval <- test[,dim(test)[2]]
names(pval) <- rownames(test)
pval <- sort(pval, decreasing=T)
if(sum(is.na(pval))>0) stop(paste("Model",
deparse(substitute(model)),"is invalid. Check if all coefficients are estimated."))
# check if all significant
if(pval[1]<sig) break # stops the loop if all remaining vars are sign.
# select var to drop
i=1
while(T){
dropvar <- names(pval)[i]
check.terms <- terms[-match(dropvar,terms)]
x <- has.interaction(dropvar,check.terms)
if(x){i=i+1;next} else {break}
} # end while(T) drop var
if(pval[i]<sig) break # stops the loop if var to remove is significant
if(verbose){
cat("\n--------\nTerm dropped in step",counter,":",dropvar,"\n--------\n\n")
}
#update terms, scopevars and model
scopevars <- scopevars[-match(dropvar,scopevars)]
terms <- terms[-match(dropvar,terms)]
formul <- as.formula(paste(".~.-",dropvar))
model <- update(model,formul)
if(length(scopevars)==0) {
warning("All variables are thrown out of the model.\n",
"No model could be specified.")
return()
}
counter=counter+1
} # end while(T) main loop
return(model)
}
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.