# SCCS @(#)residuals.survreg.s 4.12 02/06/99 # # Residuals for survreg objects residuals.survreg <- function(object, type=c('response', 'deviance', 'dfbeta', 'dfbetas', 'working', 'ldcase', 'ldresp', 'ldshape', 'matrix'), rsigma =TRUE, collapse=FALSE, weighted=FALSE, ...) { type <-match.arg(type) n <- length(object$linear.predictors) Terms <- object$terms if(!inherits(Terms, "terms")) stop("invalid terms component of object") cluster<-untangle.specials(Terms,"cluster")$terms if (length(cluster)) Terms<-Terms[-cluster] strata <- attr(Terms, 'specials')$strata coef <- object$coefficients intercept <- attr(Terms, "intercept") response <- attr(Terms, "response") weights <- object$weights if (is.null(weights)) weighted <- FALSE # # What do I need to do the computations? # if (type=='response' || type=='deviance') need.x <-FALSE else need.x <- TRUE if (type=='ldshape' || type=='ldcase') need.strata <- TRUE else need.strata <- FALSE need.y <- TRUE # grab what I need if (need.strata || (need.y && is.null(object$y)) || (need.x && is.null(object$x)) ) { # I need the model frame if (is.null(object$model)) m <- model.frame(object) else m <- object$model } if (need.strata && !is.null(strata)) { temp <- untangle.specials(Terms, 'strata', 1) Terms2 <- Terms[-temp$terms] if (length(temp$vars)==1) strata.keep <- m[[temp$vars]] else strata.keep <- strata(m[,temp$vars], shortlabel=TRUE) strata <- as.numeric(strata.keep) nstrata <- max(strata) sigma <- object$scale[strata] } else { strata <- rep(1,n) nstrata <- 1 sigma <- object$scale Terms2 <- Terms } if (need.x){ x <- object$x if (is.null(x)) x <- model.matrix(Terms2, m) } if (need.y) { y <- object$y if (is.null(y)) y <- model.extract(m, 'response') status <- y[,ncol(y)] } # # Grab the distribution # if (is.character(object$dist)) dd <- survreg.distributions[[object$dist]] else dd <- object$dist if (is.null(dd$itrans)) { itrans <- dtrans <-function(x)x } else { itrans <- dd$itrans dtrans <- dd$dtrans } if (!is.null(dd$dist)) dd <- survreg.distributions[[dd$dist]] deviance <- dd$deviance dens <- dd$density nvar <- length(object$coefficients) if (rsigma) vv <- object$var else vv <- object$var[1:nvar, 1:nvar] # Create the matrix of derivatives # The "density" function returns F, 1-F, f, f'/f, and f''/f if (type != 'response') { status <- y[,ncol(y)] eta <- object$linear.predictors z <- (y[,1] - eta)/sigma dmat <- dens(z, object$parms) dtemp<- dmat[,3] * dmat[,4] #f' if (any(status==3)) { z2 <- (y[,2] - eta)/sigma dmat2 <- dens(z2, object$parms) } else { dmat2 <- dmat #dummy values z2 <- 0 } deriv <- matrix(n,6) tdenom <- ((status==0) * dmat[,2]) + ((status==1) * 1 ) + ((status==2) * dmat[,1]) + ((status==3) * ifelse(z>0, dmat[,2]-dmat2[,2], dmat2[,1] - dmat[,1])) g <- log(ifelse(status==1, dmat[,3]/sigma, tdenom)) tdenom <- 1/(tdenom* sigma) dg <- -tdenom *(((status==0) * (0-dmat[,3])) + ((status==1) * dmat[,4]) + ((status==2) * dmat[,3]) + ((status==3) * (dmat2[,3]- dmat[,3]))) ddg <- (tdenom/sigma)*(((status==0) * (0- dtemp)) + ((status==1) * dmat[,5]) + ((status==2) * dtemp) + ((status==3) * (dmat2[,3]*dmat2[,4] - dtemp))) td2 <- tdenom * sigma ds <- ifelse(status<3, dg * sigma * z, td2*(z2*dmat2[,3] - z*dmat[,3])) dds <- ifelse(status<3, ddg* (sigma*z)^2, td2*(z2*z2*dmat2[,3]*dmat2[,4] - z * z*dmat[,3] * dmat[,4])) dsg <- ifelse(status<3, ddg* sigma*z, td2 *(z2*dmat2[,3]*dmat2[,4] - z*dtemp)) deriv <- cbind(g, dg, ddg=ddg- dg^2, ds = ifelse(status==1, ds-1, ds), dds=dds - ds*(1+ds), dsg=dsg - dg*(1+ds)) } # # Now, lay out the code one case at a time. # There is some repetition this way, but otherwise the code gets # too complicated. # if (type=='response') { yhat0 <- deviance(y, object$scale[strata], object$parms) rr <- itrans(yhat0$center) - itrans(object$linear.predictor) } else if (type=='deviance') { yhat0 <- deviance(y, object$scale[strata], object$parms) rr <- (-1)*deriv[,2]/deriv[,3] #working residuals rr <- sign(rr)* sqrt(2*(yhat0$loglik - deriv[,1])) } else if (type=='dfbeta' || type== 'dfbetas') { score <- deriv[,2] * x # score residuals if (rsigma) score <- cbind(score, deriv[,4]) rr <- score %*% vv if (type=='dfbetas') rr <- rr %*% diag(1/sqrt(diag(vv))) } else if (type=='working') rr <- (-1)*deriv[,2]/deriv[,3] else if (type=='ldcase'){ score <- deriv[,2] * x if (rsigma) score <- cbind(score, deriv[,4]) dfbeta<- score %*% vv rr <- apply(dfbeta*score,1,sum) } else if (type=='ldresp') { rscore <- deriv[,3] * (x * sigma) if (rsigma) rscore <- cbind(rscore, deriv[,6] * sigma) temp <- rscore %*% vv rr <- apply(rscore * temp, 1 , sum) } else if (type=='ldshape') { sscore <- deriv[,6] *x if (rsigma) sscore <- cbind(sscore, deriv[,5]) temp <- sscore %*% vv rr <- apply(sscore * temp, 1, sum) } else { #type = matrix rr <- deriv } # # Multiply up by case weights, if requested # if (weighted) rr <- rr * weights #Expand out the missing values in the result if (!is.null(object$na.action)) { rr <- naresid(object$na.action, rr) if (is.matrix(rr)) n <- nrow(rr) else n <- length(rr) } # Collapse if desired if (!missing(collapse)) { if (length(collapse) !=n) stop("Wrong length for 'collapse'") rr <- rowsum(rr, collapse) } rr }