################################################################ # null.residuals <- function(model.lm) { if(exists("y.null", envir=parent.frame())) gaga <- y.null else gaga <- NULL y.null <<- rnorm(length(residuals(model.lm))) null.lm <- update(model.lm, y.null ~ .) if(is.null(gaga)) rm(y.null, envir=parent.frame()) else y.null <<- gaga return(residuals(null.lm) * sqrt(deviance(model.lm) / deviance(null.lm))) } # The relevant lines above begin with "y.null <<- ..." and "null.lm <- ...", # whereas the two lines "if(..." are silly complications of R semantics # that I don't want to explain. res.vs.fits <- function(model.lm, ident=F) { windows(width=9, height=6) par(mfcol=c(2,3), mgp=c(1.5,0.5,0), mar=c(2.5,2.5,1,1)) fit <- fitted.values(model.lm) res <- residuals(model.lm) ylim <- c(-1,1)*max(abs(res)) for(i in 1:5) plot(x=fit, y=null.residuals(model.lm), pch=16, xlab="Fitted", ylab="Null Resid", ylim=ylim) plot(x=fit, y=res, pch=16, xlab="Fitted", ylab="Actual Resid", ylim=ylim) if(ident) { cat("Identify odd points in the last plot; abort when done...\n") identify(x=fit, y=res, labels=names(res)) } } res.vs.qnorm <- function(model.lm, ident=F) { windows(width=9, height=6) par(mfcol=c(2,3), mgp=c(1.5,0.5,0), mar=c(2.5,2.5,1,1)) res.sort <- sort(residuals(model.lm)) n <- length(res.sort) quant <- qnorm(1:n/(n+1)) ylim <- c(-1,1)*max(abs(res.sort)) sd <- sqrt(deviance(model.lm) / df.residual(model.lm)); for(i in 1:5) { plot(quant, sort(null.residuals(model.lm)), pch=16, xlab="Normal Quantiles", ylab="Null Resid", ylim=ylim) abline(a=0, b=sd) } plot(quant, res.sort, pch=16, xlab="Norm. Quantiles", ylab="Actual Resid", ylim=ylim) abline(a=0, b=sd) if(ident) { cat("Identify odd points in the last plot; abort when done...\n") identify(x=quant, y=res.sort, labels=names(res.sort)) } } res.vs.order <- function(model.lm, ident=F) { windows(width=9, height=6) par(mfcol=c(2,3), mgp=c(1.5,0.5,0), mar=c(2.5,2.5,1,1)) res <- residuals(model.lm) ord <- 1:length(res) ylim <- c(-1,1)*max(abs(res)) for(i in 1:5) plot(ord, null.residuals(model.lm), pch=16, xlab="Order", ylab="Null Resid", ylim=ylim) plot(ord, res, pch=16, xlab="Order", ylab="Actual Res", ylim=ylim) if(ident) { cat("Identify odd points in the last plot; abort when done...\n") identify(x=ord, y=res, labels=names(res)) } } stdize <- function(x) (x-min(x))/(max(x)-min(x)) res.vs.predictors <- function(model.lm, preds=names(model.lm$model)[-1], new.window=T) { res <- stdize(residuals(model.lm))*.9+1.1 res.null <- stdize(null.residuals(model.lm))*.9 if(new.window) windows(width=length(preds)*3, height=2*3) par(mfcol=c(1,length(preds)), mar=c(.5,.5,.5,.5)) for(pred in preds) { x <- model.lm$model[,pred]; x.range <- range(x) plot(x.range, c(0,2), type="n", xaxt="n", yaxt="n", xlab="", ylab="") text(mean(x.range), 1, pred) points(x, res, pch=16, cex=.5, xlab=pred, ylab="Actual Res") lines(lowess(x,res)) points(x, res.null, pch=16, cex=.5, xlab=pred, ylab="Null Res") lines(lowess(x,res.null)) } } partial.res.plot <- function(x,y) { p <- ncol(x); x <- as.matrix(x) # Why can't lm take data frames here? windows(width=ceiling(p/4)*3, height=4*3) par(mfcol=c(4,ceiling(p/4)), mgp=c(1.5,0.5,0), mar=c(2.5,2.5,0.5,0.5)) for(i in 1:p) plot(x=resid(lm(x[,i] ~ x[,-i])), y=resid(lm(y ~ x[,-i])), cex=0.5, pch=16, xlab=colnames(x)[i], ylab="y...") }