home *** CD-ROM | disk | FTP | other *** search
/ Big Green CD 8 / BGCD_8_Dev.iso / NEXTSTEP / UNIX / Educational / R-0.49-MI / R-0.49-I / library / survival4 < prev   
Encoding:
Text File  |  1997-09-14  |  156.0 KB  |  5,226 lines

  1. require(splines)
  2.  
  3. "model.data.frame" <-
  4. function (...) 
  5. {
  6.     cn <- as.character(substitute(list(...))[-1])
  7.     rval<-data.frame(..., col.names = cn, as.is = TRUE)
  8.     names(rval)<-cn
  9.     rval
  10. }
  11. "MyUseMethod" <-
  12. function (generic, classobj = NULL) 
  13.         call <- sys.call(sys.parent())
  14.     if (is.null(classobj)) 
  15.         classobj <- eval(call[[2]], sys.frame(sys.parent()))
  16.     classlist <- class(classobj)
  17.     classlist <- c(classlist, "default")
  18.     while (!exists(paste(generic, classlist[[1]], sep = "."
  19.     ),mode="function",inherits=TRUE) && length(classlist) > 1) classlist <- classlist[-1]
  20.         methodname<-paste(generic, classlist[[1]], sep = "."
  21.     )
  22.     if (!exists(methodname,mode="function",inherits=TRUE))
  23.         stop("No method found")
  24.     call[[1]] <- as.name(methodname)
  25.     eval(call, sys.frame(-2))
  26. }
  27.  
  28. delete.response<- function (termobj) 
  29.     terms(reformulate(attr(termobj, "term.labels"), NULL),
  30.          specials = names(attr(termobj, "specials"))
  31.         )
  32.  
  33. all.equal <- function(x,y){
  34.      as.logical(prod(as.numeric((abs(x-y)<.Machine$double.eps) || (is.na(x) && is.na(y)))))
  35. }
  36. "reformulate" <- function (termlabels, response = NULL) 
  37. {
  38.   if (is.null(response)){
  39.     termtext<-paste("~", paste(termlabels, collapse = "+"),collapse = "")
  40.     termobj<-eval(parse(text = termtext)[[1]])
  41.   }
  42.   else {
  43.     termtext <- paste("response", "~", paste(termlabels, collapse = "+"), 
  44.         collapse = "")
  45.     termobj <- eval(parse(text = termtext)[[1]])
  46.     termobj[[2]] <- response
  47.   }
  48.     termobj
  49. }
  50.  
  51.  
  52. drop.terms <-function(termobj, dropx = NULL, keep.response = F) 
  53. {
  54.     if (is.null(dropx)) 
  55.         termobj
  56.     else {
  57.         newformula <- reformulate(attr(termobj, "term.labels")[-dropx], if (keep.response) termobj[[2]] else NULL)
  58.         terms(newformula, specials = names(attr(termobj, "specials")))
  59.     }
  60. }
  61.  
  62. "pmin" <- function (..., na.rm = FALSE) 
  63. {
  64.     elts <- list(...)
  65.     minmm <- as.vector(elts[[1]])
  66.     for (each in elts[-1]) {
  67.         work <- cbind(minmm, as.vector(each))
  68.         nas <- is.na(work)
  69.         work[, 1][nas[, 1]] <- work[, 2][nas[, 1]]
  70.         work[, 2][nas[, 2]] <- work[, 1][nas[, 2]]
  71.         change <- work[, 1] > work[, 2]
  72.         work[, 1][change] <- work[, 2][change]
  73.         if (!na.rm) 
  74.             work[, 1][nas[, 1] + nas[, 2] > 0] <- NA
  75.         minmm <- work[, 1]
  76.     }
  77.     attributes(minmm)<-attributes(elts[[1]])
  78.     minmm
  79. }
  80.  
  81. "pmax" <- function (..., na.rm = FALSE) 
  82. {
  83.     elts <- list(...)
  84.     maxmm <- as.vector(elts[[1]])
  85.     for (each in elts[-1]) {
  86.         work <- cbind(maxmm, as.vector(each))
  87.         nas <- is.na(work)
  88.         work[, 1][nas[, 1]] <- work[, 2][nas[, 1]]
  89.         work[, 2][nas[, 2]] <- work[, 1][nas[, 2]]
  90.         change <- work[, 1] < work[, 2]
  91.         work[, 1][change] <- work[, 2][change]
  92.         if (!na.rm) 
  93.             work[, 1][nas[, 1] + nas[, 2] > 0] <- NA
  94.         maxmm <- work[, 1]
  95.     }
  96.     attributes(maxmm)<-attributes(elts[[1]])
  97.     maxmm
  98. }
  99. "[.Surv" <-function (xx, i=NULL, j=NULL, drop = F) 
  100. {
  101.   x<-xx
  102.     temp <- class(x)
  103.     type <- attr(x, "type")
  104.     class(x) <- NULL
  105.     attr(x, "type") <- NULL
  106.     if (missing(j)) {
  107.         x <- x[i, , drop = drop]
  108.         class(x) <- temp
  109.         attr(x, "type") <- type
  110.         x
  111.     }
  112.     else subsetfix(x,i,j,drop=drop | missing(drop))
  113. }
  114. "subsetfix" <-
  115. function (x, i = NULL, j = NULL, drop = F) 
  116. {
  117.     y <- x
  118.     y <- data.frame(y)
  119.     if (is.null(i)) {
  120.         if (is.null(j)) {
  121.             return(x)
  122.         }
  123.         else { 
  124.           if (length(j)>1){
  125.             return(as.matrix(y[,j,drop=drop]))
  126.           }
  127.           else{
  128.             return(unclass(y[, j, drop = drop]))
  129.               }
  130.         }
  131.     }
  132.     else {
  133.         if (is.null(j)) {
  134.             return(unclass(y[i, , drop = drop]))
  135.         }
  136.         else {
  137.             return(unclass(y[i, j, drop = drop]))
  138.         }
  139.     }
  140. }
  141.  
  142.  
  143. #data.frame<- function (..., row.names = NULL, col.names = NULL, as.is = FALSE) 
  144. #{
  145. ##    frame <- list(...)
  146. #    if (is.null(col.names)) {
  147. #        v <- substitute(list(...))[-1]
  148. #        for (i in 1:length(v)) if (!is.symbol(v[[i]])) 
  149. #            v[[i]] <- paste("X", i, sep = "")
  150. #        arg.names <- as.character(v)
  151. #        col.names <- names(frame)
  152. #        if (is.null(col.names)) 
  153. #            col.names <- arg.names
  154. #        else {
  155. #            nameless <- (nchar(col.names) == 0)
  156. #            col.names[nameless] <- arg.names[nameless]
  157. #        }
  158. #    }
  159. #    names(frame) <- as.character(col.names)
  160. #    for (i in 1:length(frame)) if (is.list(frame[[i]])) 
  161. #        for (j in 1:length(frame[[i]])) {
  162. #            if (!is.numeric(frame[[i]][[j]]) && !is.factor(frame[[i]][[j]])) 
  163. #                frame[[i]][[j]] <- numeric.or.factor(frame[[i]][[j]])
  164. #        }
  165. #    else {
  166. #        if (!is.numeric(frame[[i]]) && !is.factor(frame[[i]])) 
  167. #            frame[[i]] <- numeric.or.factor(frame[[i]])
  168. #    }
  169. #    nn<-names(frame)
  170. #    rval <-.Internal(data.frame(frame, as.character(row.names), as.logical(as.is)))
  171. #    rval
  172. #}
  173.  
  174.  
  175.  
  176.  sort.list<-function(...) order(...)
  177.  
  178. "[.formula"<-function(f,i,...){ 
  179.   tt<-terms.formula(f)[i]
  180.   attributes(tt)<-list(class="formula") 
  181.   tt
  182. }
  183.  
  184. "[.terms"<-function(termobj,i){
  185.   resp<-if (attr(termobj,"response")) termobj[[2]] else NULL
  186.   newformula<-reformulate(attr(termobj, "term.labels")[i], resp)
  187.   terms(newformula, specials = names(attr(termobj, "specials")))
  188. }
  189.  
  190. is.category <- function(x) inherits(x,"factor") || is.factor(x)
  191.  
  192. "model.frame" <-function (formula, data = sys.frame(sys.parent()), subset = NULL, na.action = eval(as.name(options("na.action")$na.action)), use.data = TRUE, process.offsets = TRUE, ...) 
  193.         if (!is.null(formula$model) && missing(data)) 
  194.       return(formula$model)
  195.  
  196.     if (!missing(data) || is.null(formula$model.frame)) {
  197.         dotsdata <- if (use.data) 
  198.             data
  199.         else sys.frame(sys.parent())
  200.         newframe <- substitute(list(...))
  201.         dots <- eval(newframe, dotsdata)
  202.         if (!is.null(dots)) {
  203.             real.dots <- !unlist(lapply(dots, is.null))
  204.             newframe <- as.call(newframe[c(T, real.dots)])
  205.             dots <- dots[real.dots]
  206.         }
  207.         Terms <- terms(formula)
  208.         frame <- attr(Terms, "variables")
  209.         name.process <- function(x) paste("(", x, ")", sep = "")
  210.         if (missing(data)) {
  211.           if (is.null(formula$call$data))
  212.             data<-environment(NULL)
  213.           else
  214.             data <- eval(formula$call$data)
  215.         }
  216.         if (!(missing(subset) || exists(as.character(match.call()$subset), inherits = FALSE
  217.         ))) 
  218.             subset <- eval(match.call()$subset, data)
  219.         if (is.null(dots)) 
  220.             rval <- na.action(eval(frame, data)[subset, , drop = FALSE])
  221.         else {
  222.             dotnames <- sapply(names(eval(dots, data)), name.process)
  223.             val <- eval(frame, data)
  224.             newframe[[1]] <- as.name("model.data.frame")
  225.             for (i in 1:length(dots)) newframe[[i + 1]] <- dots[[i]]
  226.             dotsval <- eval(newframe, dotsdata)
  227.             names(dotsval) <- dotnames
  228.             if (dim(val)[1] == dim(dotsval)[1]) 
  229.                 newval <- c(val, dotsval)
  230.             else stop("Mismatched dimensions in model.frame")
  231.             class(newval) <- "data.frame"
  232.             rval <- na.action(newval[subset, , drop = FALSE])
  233.         }
  234.         attr(rval, "terms") <- Terms
  235.         offset.pos <- attr(Terms, "offset")
  236.         if (process.offsets && (length(offset.pos) > 0)) {
  237.             offset.total <- as.vector(as.matrix(rval[, offset.pos]) %*% rep(1, length(offset.pos
  238.             )))
  239.             rval[[offset.pos[1]]] <- offset.total
  240.             names(rval)[offset.pos[1]] <- "(offset)"
  241.         }
  242.         rval
  243.     }
  244.     else formula$model.frame
  245. }
  246.  
  247.  
  248.  
  249.  
  250.  
  251.  
  252.  
  253.  
  254. #SCCS 12/22/95 @(#)Surv.s    4.17
  255. # Package up surivival type data as a structure
  256. #
  257. Surv <- function(time, time2, event,
  258.           type=c('right', 'left', 'interval', 'counting', 'interval2'),
  259.                origin=0) {
  260.     nn <- length(time)
  261.     ng <- nargs()
  262.     if (missing(type)) {
  263.     if (ng==1 || ng==2) type <- 'right'
  264.     else if (ng==3)     type <- 'counting'
  265.     else stop("Invalid number of arguments")
  266.     }
  267.     else {
  268.     type <- match.arg(type)
  269.     ng <- ng-1
  270.     if (ng!=3 && (type=='interval' || type =='counting'))
  271.         stop("Wrong number of args for this type of survival data")
  272.     if (ng!=2 && (type=='right' || type=='left' ||  type=='interval2'))
  273.         stop("Wrong number of args for this type of survival data")
  274.     }
  275.     who <- !is.na(time)
  276.  
  277.     if (ng==1) {
  278.     if (!is.numeric(time)) stop ("Time variable is not numeric")
  279.     else if (any(time[who]<0))  stop ("Time variable must be >= 0")
  280.     ss <- cbind(time, 1)
  281.     dimnames(ss) <- list(NULL, c("time", "status"))
  282.     }
  283.     else if (type=='right' || type=='left') {
  284.     if (!is.numeric(time)) stop ("Time variable is not numeric")
  285.     else if (any(time[who]<0))  stop ("Time variable must be >= 0")
  286.     if (length(time2) != nn) stop ("Time and status are different lengths")
  287.     if (is.logical(time2)) status <- 1*time2
  288.         else  if (is.numeric(time2)) {
  289.         who2 <- !is.na(time2)
  290.         status <- time2 - (max(time2[who2]) -1)
  291.         if (any(status[who2] !=0  & status[who2]!=1))
  292.                 stop ("Invalid status value")
  293.         }
  294.         else stop("Invalid status value")
  295.      ss <- cbind(time, status)
  296.      dimnames(ss) <- list(NULL, c("time", "status"))
  297.     }
  298.     else  if (type=='counting') {
  299.     if (length(time2) !=nn) stop ("Start and stop are different lengths")
  300.     if (length(event)!=nn) stop ("Start and event are different lengths")
  301.     if (!is.numeric(time))stop("Start time is not numeric")
  302.     if (!is.numeric(time2)) stop("Stop time is not numeric")
  303.     who3 <- who & !is.na(time2)
  304.     if (any (time[who3]>= time2[who3]))stop("Stop time must be > start time")
  305.     if (is.logical(event)) status <- 1*event
  306.         else  if (is.numeric(event)) {
  307.         who2 <- !is.na(event)
  308.         status <- event - min(event[who2])
  309.         if (any(status[who2] !=0  & status[who2]!=1))
  310.                 stop("Invalid status value")
  311.         }
  312.         else stop("Invalid status value")
  313.     ss <- cbind(time-origin, time2-origin, status)
  314.     }
  315.  
  316.     else {  #interval censored data
  317.     if (type=='interval2') {
  318.         event <- ifelse(is.na(time), 2,
  319.              ifelse(is.na(time2),0,
  320.              ifelse(time==time2, 1,3)))
  321.         if (any(time[event==3] > time2[event==3]))
  322.         stop("Invalid interval: start > stop")
  323.         time <- ifelse(event!=2, time, time2)
  324.         type <- 'interval'
  325.         }
  326.     else {
  327.         temp <- event[!is.na(event)]
  328.         if (!is.numeric(temp)) stop("Status indicator must be numeric")
  329.         if (length(temp)>0 && any(temp!= floor(temp) | temp<0 | temp>3))
  330.         stop("Status indicator must be 0, 1, 2 or 3")
  331.         }
  332.     status <- event
  333.     ss <- cbind(time, ifelse(!is.na(event) & event==3, time2, 1),
  334.                 status)
  335.     }
  336.  
  337.     attr(ss, "class") <- c("Surv")
  338.     attr(ss, "type")  <- type
  339.     ss
  340.     }
  341.  
  342. print.Surv <- function(xx, quote=F, ...)
  343.     invisible(print(as.character.Surv(xx), quote=quote, ...))
  344.  
  345. as.character.Surv <- function(xx) {
  346.     class(xx) <- NULL
  347.     type <- attr(xx, 'type')
  348.     if (type=='right') {
  349.     temp <- xx[,2]
  350.     temp <- ifelse(is.na(temp), "?", ifelse(temp==0, "+"," "))
  351.     paste(format(xx[,1]), temp, sep='')
  352.     }
  353.     else if (type=='counting') {
  354.     temp <- xx[,3]
  355.     temp <- ifelse(is.na(temp), "?", ifelse(temp==0, "+"," "))
  356.     paste('(', format(xx[,1]), ',', format(xx[,2]), temp,
  357.              ']', sep='')
  358.     }
  359.     else if (type=='left') {
  360.     temp <- xx[,2]
  361.     temp <- ifelse(is.na(temp), "?", ifelse(temp==0, "<"," "))
  362.     paste(temp, format(xx[,1]), sep='')
  363.     }
  364.     else {   #interval type
  365.     stat <- xx[,3]
  366.     temp <- c("+", "", "-", "]")[stat+1]
  367.     temp2 <- ifelse(stat==3,
  368.              paste("[", format(xx[,1]), ", ",format(xx[,2]), sep=''),
  369.              format(xx[,1]))
  370.     ifelse(is.na(stat), "NA", paste(temp2, temp, sep=''))
  371.     }
  372.     }
  373.  
  374. #"[.Surv" <- function(x,i,j, drop=F) {
  375. #   temp <- class(x)
  376. #    type <- attr(x, "type")
  377. #    class(x) <- NULL
  378. #    attr(x, 'type') <- NULL
  379. #    if (missing(j)) {
  380. #    x <- x[i,,drop=drop]
  381. #    class(x) <- temp
  382. #    attr(x, "type") <- type
  383. #    x
  384. #    }
  385. #    else NextMethod("[")
  386. #    }
  387.  
  388. is.na.Surv <- function(x) {
  389.     class(x) <- NULL
  390.     as.vector( (1* is.na(x))%*% rep(1, ncol(x)) >0)
  391.     }
  392.  
  393. Math.Surv <- function(...)  stop("Invalid operation on a survival time")
  394. Ops.Surv  <- function(...)  stop("Invalid operation on a survival time")
  395. Summary.Surv<- function(...) stop("Invalid operation on a survival time")
  396. is.Surv <- function(x) inherits(x, 'Surv')
  397. #SCCS @(#)agexact.fit.s    4.16 02/28/95
  398. agexact.fit <- function(x, y, strata, offset, iter.max,
  399.             eps, weights, init, method, rownames)
  400.     {
  401.     if (!is.matrix(x)) stop("Invalid formula for cox fitting function")
  402.     if (!is.null(weights) && any(weights!=1))
  403.       stop("Case weights are not supported for the exact method")
  404.     n <- nrow(x)
  405.     nvar <- ncol(x)
  406.     if (ncol(y)==3) {
  407.     start <- y[,1]
  408.     stopp <- y[,2]
  409.     event <- y[,3]
  410.     }
  411.     else {
  412.     start <- rep(0,n)
  413.     stopp <- y[,1]
  414.     event <- y[,2]
  415.     }
  416.  
  417.     # Sort the data (or rather, get a list of sorted indices)
  418.     if (length(strata)==0) {
  419.     sorted <- order(stopp, -event)
  420.     newstrat <- as.integer(rep(0,n))
  421.     }
  422.     else {
  423.     sorted <- order(strata, stopp, -event)
  424.     strata <- (as.numeric(strata))[sorted]
  425.     newstrat <- as.integer(c(1*(diff(strata)!=0), 1))
  426.     }
  427.     if (is.null(offset)) offset <- rep(0,n)
  428.  
  429.     sstart <- as.double(start[sorted])
  430.     sstop <- as.double(stopp[sorted])
  431.     sstat <- as.integer(event[sorted])
  432.  
  433.     if (is.null(nvar)) {
  434.     # A special case: Null model.  Not worth coding up
  435.     stop("Cannot handle a null model + exact calculation (yet)")
  436.     }
  437.  
  438.     if (!is.null(init)) {
  439.     if (length(init) != nvar) stop("Wrong length for inital values")
  440.     }
  441.     else init <- rep(0,nvar)
  442.  
  443.     agfit <- .C("agexact", iter= as.integer(iter.max),
  444.            as.integer(n),
  445.            as.integer(nvar), sstart, sstop,
  446.            sstat,
  447.            x= x[sorted,],
  448.            as.double(offset[sorted] - mean(offset)),
  449.            newstrat,
  450.            means = double(nvar),
  451.            coef= as.double(init),
  452.            u = double(nvar),
  453.            imat= double(nvar*nvar), loglik=double(2),
  454.            flag=integer(1),
  455.            double(2*nvar*nvar +nvar*4 + n),
  456.            integer(2*n),
  457.            as.double(eps),
  458.            sctest=double(1) )
  459.  
  460.     var <- matrix(agfit$imat,nvar,nvar)
  461.     coef <- agfit$coef
  462.     if (agfit$flag < nvar) which.sing <- diag(var)==0
  463.     else which.sing <- rep(F,nvar)
  464.  
  465.     infs <- abs(agfit$u %*% var)
  466.     if (iter.max >1) {
  467.     if (agfit$flag == 1000)
  468.            warning("Ran out of iterations and did not converge")
  469.     else if (any((infs > eps) & (infs > sqrt(eps)*abs(coef))))
  470.         warning(paste("Loglik converged before variable ",
  471.               paste((1:nvar)[(infs>eps)],collapse=","),
  472.               "; beta may be infinite. "))
  473.     }
  474.  
  475.     names(coef) <- dimnames(x)[[2]]
  476.     lp  <- x %*% coef + offset - sum(coef *agfit$means)
  477.     score <- as.double(exp(lp[sorted]))
  478.     agres <- .C("agmart",
  479.            as.integer(n),
  480.            as.integer(0),
  481.            sstart, sstop,
  482.            sstat,
  483.            score,
  484.            rep(1,n),
  485.            newstrat,
  486.            resid=double(n))
  487.     resid _ double(n)
  488.     resid[sorted] <- agres$resid
  489.     names(resid) <- rownames
  490.     coef[which.sing] <- NA
  491.  
  492.     list(coefficients  = coef,
  493.         var    = var,
  494.         loglik = agfit$loglik,
  495.         score  = agfit$sctest,
  496.         iter   = agfit$iter,
  497.         linear.predictors = lp,
  498.         residuals = resid,
  499.         means = agfit$means,
  500.         method= 'coxph')
  501.     }
  502. #SCCS @(#)agreg.fit.s    4.15 02/28/95
  503. agreg.fit <- function(x, y, strata, offset, init, iter.max,
  504.             eps, weights, method, rownames)
  505.     {
  506.     n <- nrow(y)
  507.     nvar <- ncol(x)
  508.     start <- y[,1]
  509.     stopp <- y[,2]
  510.     event <- y[,3]
  511.  
  512.     # Sort the data (or rather, get a list of sorted indices)
  513.     if (length(strata)==0) {
  514.     sorted <- order(stopp, -event)
  515.     newstrat <- as.integer(rep(0,n))
  516.     }
  517.     else {
  518.     sorted <- order(strata, stopp, -event)
  519.     strata <- (as.numeric(strata))[sorted]
  520.     newstrat <- as.integer(c(1*(diff(strata)!=0), 1))
  521.     }
  522.     if (missing(offset) || is.null(offset)) offset <- rep(0,n)
  523.     if (missing(weights)|| is.null(weights))weights<- rep(1,n)
  524.     else {
  525.     if (any(weights<=0)) stop("Invalid weights, must be >0")
  526.     weights <- weights[sorted]
  527.     }
  528.     sstart <- as.double(start[sorted])
  529.     sstop <- as.double(stopp[sorted])
  530.     sstat <- as.integer(event[sorted])
  531.  
  532.     if (is.null(nvar)) {
  533.     # A special case: Null model.  Just return obvious stuff
  534.     score <- as.double(exp(offset[sorted]))
  535.     agfit <- .C("agfit_null",
  536.                as.integer(n),
  537.                as.integer(method=='efron'),
  538.                sstart, sstop,
  539.                sstat,
  540.                offset[sorted],
  541.                as.double(weights),
  542.                newstrat,
  543.                loglik=double(1))
  544.  
  545.     agres <- .C("agmart",
  546.                as.integer(n),
  547.                as.integer(method=='efron'),
  548.                sstart, sstop,
  549.                sstat,
  550.                score,
  551.                as.double(weights),
  552.                newstrat,
  553.                resid=double(n))
  554.  
  555.     resid _ double(n)
  556.     resid[sorted] <- agres$resid
  557.     names(resid) <- rownames
  558.  
  559.     list(loglik=agfit$loglik,
  560.          linear.predictors = offset,
  561.          residuals = resid,
  562.          method= c("coxph.null", 'coxph') )
  563.     }
  564.  
  565.     else {
  566.     if (!is.null(init)) {
  567.         if (length(init) != nvar) stop("Wrong length for inital values")
  568.         }
  569.     else init <- rep(0,nvar)
  570.  
  571.     agfit <- .C("agfit2", iter= as.integer(iter.max),
  572.                as.integer(n),
  573.                as.integer(nvar), sstart, sstop,
  574.                sstat,
  575.                x= x[sorted,],
  576.                as.double(offset[sorted] - mean(offset)),
  577.                as.double(weights),
  578.                newstrat,
  579.                means = double(nvar),
  580.                coef= as.double(init),
  581.                u = double(nvar),
  582.                imat= double(nvar*nvar), loglik=double(2),
  583.                flag=integer(1),
  584.                double(2*nvar*nvar +nvar*3 + n),
  585.                integer(n),
  586.                as.double(eps),
  587.                sctest=as.double(method=='efron') )
  588.  
  589.     var <- matrix(agfit$imat,nvar,nvar)
  590.     coef <- agfit$coef
  591.     if (agfit$flag < nvar) which.sing <- diag(var)==0
  592.     else which.sing <- rep(F,nvar)
  593.  
  594.     infs <- abs(agfit$u %*% var)
  595.     if (iter.max >1) {
  596.         if (agfit$flag == 1000)
  597.            warning("Ran out of iterations and did not converge")
  598.         else if (any((infs > eps) & (infs > sqrt(eps)*abs(coef))))
  599.         warning(paste("Loglik converged before variable ",
  600.               paste((1:nvar)[(infs>eps)],collapse=","),
  601.               "; beta may be infinite. "))
  602.         }
  603.  
  604.     names(coef) <- dimnames(x)[[2]]
  605.     lp  <- x %*% coef + offset - sum(coef *agfit$means)
  606.     score <- as.double(exp(lp[sorted]))
  607.     agres <- .C("agmart",
  608.                as.integer(n),
  609.                as.integer(method=='efron'),
  610.                sstart, sstop,
  611.                sstat,
  612.                score,
  613.                as.double(weights),
  614.                newstrat,
  615.                resid=double(n))
  616.  
  617.     resid _ double(n)
  618.     resid[sorted] <- agres$resid
  619.     names(resid) <- rownames
  620.     coef[which.sing] <- NA
  621.  
  622.     list(coefficients  = coef,
  623.             var    = var,
  624.             loglik = agfit$loglik,
  625.             score  = agfit$sctest,
  626.             iter   = agfit$iter,
  627.             linear.predictors = as.vector(lp),
  628.             residuals = resid,
  629.             means = agfit$means,
  630.             method= 'coxph')
  631.     }
  632.     }
  633. #SCCS @(#)cluster.s    4.1 10/01/94
  634. cluster <- function(x) x
  635. # SCCS @(#)cox.zph.s    1.13 12/27/95
  636. #  Test proportional hazards
  637. #
  638. cox.zph <- function(fit, transform='km', global=T) {
  639.     call <- match.call()
  640.     if (!inherits(fit, 'coxph')) stop ("Argument must be the result of coxph")
  641.     if (inherits(fit, 'coxph.null'))
  642.     stop("The are no score residuals for a Null model")
  643.  
  644.     sresid <- resid(fit, 'schoenfeld')
  645.     varnames <- names(fit$coef)
  646.     nvar <- length(varnames)
  647.     ndead<- length(sresid)/nvar
  648.     if (nvar==1) times <- as.numeric(names(sresid))
  649.     else         times <- as.numeric(dimnames(sresid)[[1]])
  650.  
  651.     if (missing(transform) && attr(fit$y, 'type') != 'right')
  652.         transform <- 'identity'
  653.     if (is.character(transform)) {
  654.     tname <- transform
  655.     ttimes <- switch(transform,
  656.                'identity'= times,
  657.                'rank'    = rank(times),
  658.                'log'     = log(times),
  659.                'km' = {
  660.                 temp <- survfit.km(factor(rep(1,nrow(fit$y))),
  661.                             fit$y, se.fit=F)
  662.                 # A nuisance to do left cont KM
  663.                 t1 <- temp$surv[temp$n.event>0]
  664.                 t2 <- temp$n.event[temp$n.event>0]
  665.                 km <- rep(c(1,t1), c(t2,0))
  666.                 if (is.null(attr(sresid, 'strata')))
  667.                     1-km
  668.                 else (1- km[sort.list(sort.list(times))])
  669.                 },
  670.                stop("Unrecognized transform"))
  671.     }
  672.     else {
  673.     tname <- deparse(substitute(transform))
  674.     ttimes <- transform(times)
  675.     }
  676.     xx <- ttimes - mean(ttimes)
  677.  
  678.     r2 <- sresid %*% fit$var * ndead
  679.     test <- xx %*% r2        # time weighted col sums
  680.     corel <- c(cor(xx, r2))
  681.     z <- c(test^2 /(diag(fit$var)*ndead* sum(xx^2)))
  682.     Z.ph <- cbind(corel, z, 1- pchisq(z,1))
  683.  
  684.     if (global && nvar>1) {
  685.     test <- c(xx %*% sresid)
  686.     z    <- c(test %*% fit$var %*% test) * ndead / sum(xx^2)
  687.     Z.ph <- rbind(Z.ph, c(NA, z, 1-pchisq(z, ncol(sresid))))
  688.     dimnames(Z.ph) <- list(c(varnames, "GLOBAL"), c("rho", "chisq", "p"))
  689.     }
  690.     else dimnames(Z.ph) <- list(varnames, c("rho", "chisq", "p"))
  691.  
  692.     dimnames(r2) <- list(times, names(fit$coef))
  693.     temp <-list(table=Z.ph, x=ttimes, y=r2 + outer(rep(1,ndead), fit$coef),
  694.     var=fit$var, call=call, transform=tname)
  695.     class(temp) <- "cox.zph"
  696.     temp
  697.     }
  698.  
  699. "[.cox.zph" <- function(x,i, ..., drop=F) {
  700.     z<- list(table=x$table[i,,drop=drop], x=x$x, y=x$y[ ,i,drop=drop],
  701.         var=x$var[i,i, drop=drop], call=x$call,
  702.         transform=x$transform)
  703.     attributes(z) <- attributes(x)
  704.     z
  705.     }
  706. #SCCS  @(#)coxph.detail.s    4.10 07/28/95
  707. coxph.detail <-  function(object) {
  708.     method <- object$method
  709.     if (method!='breslow' && method!='efron')
  710.     stop(paste("Detailed output is not available for the", method,
  711.             "method"))
  712.     n <- length(object$residuals)
  713.     rr <- object$residual
  714.     weights <- object$weights        #always present if there are weights
  715.     x <- object$x
  716.     y <- object$y
  717.     strat <- object$strata
  718.     Terms <- object$terms
  719.     if (!inherits(Terms, 'terms'))
  720.         stop("invalid terms component of object")
  721.     strats <- attr(Terms, "specials")$strata
  722.  
  723.     if (is.null(y)  ||  is.null(x)) {
  724.     temp <- coxph.getdata(object, y=T, x=T, strata=T)
  725.     y <- temp$y
  726.     x <- temp$x
  727.     if (length(strats)) strat <- temp$strata
  728.     }
  729.  
  730.     nvar <- ncol(x)
  731.     if (ncol(y)==2) y <- cbind(-1,y)
  732.     if (is.null(strat)) {
  733.     ord <- order(y[,2], -y[,3])
  734.     newstrat <- rep(0,n)
  735.     }
  736.     else {
  737.     ord <- order(strat, y[,2], -y[,3])
  738.     newstrat <- c(diff(as.numeric(strat[ord]))!=0 ,1)
  739.     }
  740.     newstrat[n] <- 1
  741.  
  742.     # sort the data
  743.     x <- x[ord,]
  744.     y <- y[ord,]
  745.     storage.mode(y) <- 'double'
  746.     score <- exp(object$linear.predictor)[ord]
  747.     if (is.null(weights)) weights <- rep(1,n)
  748.     else                  weights <- weights[ord]
  749.  
  750.     ndeath <- sum(y[,3])
  751.     ff <- .C("coxdetail", as.integer(n),
  752.               as.integer(nvar),
  753.               ndeath= as.integer(ndeath),
  754.               y = y,
  755.               as.double(x),
  756.               as.integer(newstrat),
  757.               index =as.double(score),
  758.               weights = as.double(weights),
  759.               means= c(method=='efron', double(ndeath*nvar)),
  760.               u = double(ndeath*nvar),
  761.               i = double(ndeath*nvar*nvar),
  762.               double(nvar*(3 + 2*nvar)) )
  763.     keep <- 1:ff$ndeath
  764.     vname<- dimnames(x)[[2]]
  765.     time <- y[ff$index[keep],2]
  766.     names(time) <- NULL
  767.     means<- (matrix(ff$means,ndeath, nvar))[keep,]
  768.     score<-  matrix(ff$u, ndeath, nvar)[keep,]
  769.     var <- array(ff$i, c(nvar, nvar, ndeath))[,,keep]
  770.     if (nvar>1) {
  771.     dimnames(means) <- list(time, vname)
  772.     dimnames(score) <- list(time, vname)
  773.     dimnames(var) <- list(vname, vname, time)
  774.     }
  775.     else {
  776.     names(means) <- time
  777.     names(score) <- time
  778.     names(var) <- time
  779.     }
  780.  
  781.     dimnames(ff$y) <- NULL
  782.     temp <- list(time = time, means=means, nevent=ff$y[keep,1],
  783.      nrisk = ff$y[keep,2], hazard= ff$y[keep,3], score= score,  imat=var,
  784.      varhaz=ff$weights[keep], y=y, x=x)
  785.     if (length(strats)) temp$strata <- table((strat[ord])[ff$index[keep]])
  786.     if (!all(weights==1)) temp$weights <- weights
  787.     temp
  788.     }
  789. #SCCS 04/09/96 @(#)coxph.fit.s    4.18
  790. coxph.fit <- function(x, y, strata, offset, init, iter.max,
  791.             eps, weights, method, rownames)
  792.     {
  793.     n <-  nrow(y)
  794.     if (is.matrix(x)) nvar <- ncol(x)
  795.     else  if (length(x)==0) nvar <-0 else nvar <-1
  796.     time <- y[,1]
  797.     status <- y[,2]
  798.  
  799.     # Sort the data (or rather, get a list of sorted indices)
  800.     if (length(strata)==0) {
  801.     sorted <- order(time)
  802.     newstrat <- as.integer(rep(0,n))
  803.     }
  804.     else {
  805.     sorted <- order(strata, time)
  806.     strata <- (as.numeric(strata))[sorted]
  807.     newstrat <- as.integer(c(1*(diff(strata)!=0), 1))
  808.     }
  809.     if (missing(offset) || is.null(offset)) offset <- rep(0,n)
  810.     if (missing(weights)|| is.null(weights))weights<- rep(1,n)
  811.     else {
  812.     if (any(weights<=0)) stop("Invalid weights, must be >0")
  813.     weights <- weights[sorted]
  814.     }
  815.     stime <- as.double(time[sorted])
  816.     sstat <- as.integer(status[sorted])
  817.  
  818.     if (nvar==0) {
  819.     # A special case: Null model.
  820.     #  (This is why I need the rownames arg- can't use x' names)
  821.     score <- exp(offset[sorted])
  822.     coxfit <- .C("coxfit_null", as.integer(n),
  823.                     as.integer(method=='efron'),
  824.                     stime,
  825.                     sstat,
  826.                     exp(offset[sorted]),
  827.                     as.double(weights),
  828.                     newstrat,
  829.                     loglik=double(1),
  830.                     resid = double(n) )
  831.     resid <- double(n)
  832.     resid[sorted] <- coxfit$resid
  833.     names(resid) <- rownames
  834.  
  835.     list( loglik = coxfit$loglik,
  836.           linear.predictors = offset,
  837.           residuals = resid,
  838.           method= c('coxph.null', 'coxph') )
  839.     }
  840.  
  841.     else {
  842.     if (!missing(init) && !is.null(init)) {
  843.         if (length(init) != nvar) stop("Wrong length for inital values")
  844.         }
  845.     else init <- rep(0,nvar)
  846.  
  847.     coxfit <- .C("coxfit2", iter=as.integer(iter.max),
  848.                as.integer(n),
  849.                as.integer(nvar), stime,
  850.                sstat,
  851.                x= x[sorted,] ,
  852.                as.double(offset[sorted] - mean(offset)),
  853.                as.double(weights),
  854.                newstrat,
  855.                means= double(nvar),
  856.                coef= as.double(init),
  857.                u = double(nvar),
  858.                imat= double(nvar*nvar), loglik=double(2),
  859.                flag=integer(1),
  860.                double(2*n + 2*nvar*nvar + 3*nvar),
  861.                as.double(eps),
  862.                sctest=as.double(method=="efron") )
  863.  
  864.     var <- matrix(coxfit$imat,nvar,nvar)
  865.     coef <- coxfit$coef
  866.     if (coxfit$flag < nvar) which.sing <- diag(var)==0
  867.     else which.sing <- rep(F,nvar)
  868.  
  869.     infs <- abs(coxfit$u %*% var)
  870.     if (iter.max >1) {
  871.         if (coxfit$flag == 1000)
  872.            warning("Ran out of iterations and did not converge")
  873.         else if (any((infs > eps) & (infs > sqrt(eps)*abs(coef))))
  874.         warning(paste("Loglik converged before variable ",
  875.               paste((1:nvar)[(infs>eps)],collapse=" ,"),
  876.               "; beta may be infinite. ", sep=''))
  877.         }
  878.  
  879.     names(coef) <- dimnames(x)[[2]]
  880.     lp <- c(x %*% coef) + offset - sum(coef*coxfit$means)
  881.     score <- exp(lp[sorted])
  882.     coxres <- .C("coxmart", as.integer(n),
  883.                 as.integer(method=='efron'),
  884.                 stime,
  885.                 sstat,
  886.                 newstrat,
  887.                 score,
  888.                 weights,
  889.                 resid=double(n))
  890.     resid <- double(n)
  891.     resid[sorted] <- coxres$resid
  892.     names(resid) <- rownames
  893.     coef[which.sing] <- NA
  894.  
  895.     list(coefficients  = coef,
  896.             var    = var,
  897.             loglik = coxfit$loglik,
  898.             score  = coxfit$sctest,
  899.             iter   = coxfit$iter,
  900.             linear.predictors = as.vector(lp),
  901.             residuals = resid,
  902.             means = coxfit$means,
  903.             method='coxph')
  904.     }
  905.     }
  906. # SCCS @(#)coxph.getdata.s    4.3 09/08/94
  907. #
  908. # Reconstruct the Cox model data.  This is done in so many routines
  909. #  that I extracted it out.
  910. #
  911. # The "stratax" name is to avoid conflicts with the strata() function, but
  912. #   still allow users to type "strata" as an arg.
  913. #
  914. coxph.getdata <- function(fit, y=T, x=T, stratax=T, offset=F) {
  915.     ty <- fit$y
  916.     tx <- fit$x
  917.     strat <- fit$strata
  918.     Terms <- fit$terms
  919.     if (is.null(attr(Terms, 'offset'))) offset <- F
  920.     if (offset) x<- T
  921.     if (!inherits(Terms, 'terms'))
  922.         stop("invalid terms component of fit")
  923.     strats <- attr(Terms, "specials")$strata
  924.     if (length(strats)==0) stratax <- F
  925.  
  926.     if ( (y && is.null(ty)) || (x && is.null(tx)) ||
  927.          (stratax && is.null(strat)) || offset) {
  928.     # get the model frame
  929.     m <- fit$model
  930.     if (is.null(m)) m <- model.frame(fit)
  931.  
  932.     # Pull things out
  933.     if (y && is.null(ty)) ty <- model.extract(m, 'response')
  934.  
  935.     if (offset) toff <- model.extract(m, 'offset')
  936.  
  937.     # strata was saved in the fit if and only if x was
  938.     if (x && is.null(tx)) {
  939.         dropx <- untangle.specials(Terms, 'cluster')$terms
  940.         if (stratax) {
  941.         temp <- untangle.specials(Terms, 'strata', 1)
  942.         tx <- model.matrix("[.terms"(Terms,-c(dropx,temp$terms)), m)[,-1,drop=F]
  943.         strat <- strata(m[temp$vars], shortlabel=T)
  944.         }
  945.         else {
  946.         if (length(dropx)) tx <- model.matrix("[.terms"(Terms,-dropx), m)[,-1,drop=F]
  947.         else               tx <- model.matrix(Terms, m)[,-1,drop=F]
  948.         }
  949.         }
  950.     }
  951.     else if (offset)
  952.        toff <- fit$linear.predictors -(c(tx %*% fit$coef) - sum(fit$means*fit$coef))
  953.  
  954.     temp <- NULL
  955.     if (y) temp <- c(temp, "y=ty")
  956.     if (x) temp <- c(temp, "x=tx")
  957.     if (stratax)  temp <- c(temp, "strata=strat")
  958.     if (offset)  temp <- c(temp, "offset=toff")
  959.  
  960. ###    eval(parse(text=paste("list(", paste(temp, collapse=','), ")")))
  961.     eval(parse(text=paste("list(", paste(temp, collapse=','), ")"))[[1]])
  962.     }
  963. #SCCS @(#)coxph.rvar.s    4.3 01/18/94
  964. coxph.rvar <- function(fit, collapse) {
  965.     rcall <- match.call()
  966.     if (class(fit) != 'coxph')
  967.     stop ("First argument must be a fitted Cox model")
  968.  
  969.     if (missing(collapse)) temp <- residuals.coxph(fit, type='dfbeta')
  970.     else temp <- residuals.coxph(fit, type='dfbeta', collapse=collapse)
  971.     if (any(is.na(temp)))
  972.        if (ncol(temp)==1) temp<- temp[!is.na(temp),,drop=F]
  973.        else               temp <- temp[!is.na(temp %*% rep(1,ncol(temp))),]
  974.     fit$robust.var <- t(temp) %*% temp
  975.     fit$rcall <- rcall
  976.     fit
  977.     }
  978. #SCCS  @(#)coxph.s    4.20  08/30/96
  979. coxph <- function(formula=formula(data), data=sys.parent(),
  980.     weights, subset, na.action,
  981.     eps=.0001, init, iter.max=10,
  982.     method= c("efron", "breslow", "exact"),
  983.     singular.ok =T, robust=F,
  984.     model=F, x=F, y=T) {
  985.  
  986.     method <- match.arg(method)
  987.     call <- match.call()
  988.     m <- match.call(expand=F)
  989.     m$method <- m$model <- m$x <- m$y <- m$... <-  NULL
  990.     m$eps <- m$init <- m$iter.max <- m$robust <- m$singular.ok <- NULL
  991. ### <TSL>
  992. ###    Terms <- if(missing(data)) terms(formula, c('strata', 'cluster'))
  993. ###         else     terms(formula, c('strata', 'cluster'),data=data)    
  994.     Terms <- terms(formula, c('strata', 'cluster'))
  995. ### </TSL>
  996.     m$formula <- Terms
  997.     m[[1]] <- as.name("model.frame")
  998. ###<TSL> we will need this later when dropping terms from formula
  999.     mcopy<-m
  1000. ###</TSL>
  1001.     m <- eval(m, sys.parent())
  1002.  
  1003.     Y <- model.extract(m, "response")
  1004.     if (!inherits(Y, "Surv")) stop("Response must be a survival object")
  1005.     weights <- model.extract(m, 'weights')
  1006.     offset<- attr(Terms, "offset")
  1007.     tt <- length(offset)
  1008.     offset <- if(tt == 0)
  1009.             rep(0, nrow(Y))
  1010.           else if(tt == 1)
  1011.               m[[offset]]
  1012.           else {
  1013.             ff <- m[[offset[1]]]
  1014.             for(i in 2:tt)
  1015.                 ff <- ff + m[[offset[i]]]
  1016.             ff
  1017.             }
  1018.  
  1019.     attr(Terms,"intercept")<- 1  #Cox model always has \Lambda_0
  1020.     strats <- attr(Terms, "specials")$strata
  1021.     cluster<- attr(Terms, "specials")$cluster
  1022.     dropx <- NULL
  1023.     if (length(cluster)) {
  1024.     if (missing(robust)) robust <- T
  1025.     tempc <- untangle.specials(Terms, 'cluster', 1:10)
  1026.     ord <- attr(Terms, 'order')[tempc$terms]
  1027.     if (any(ord>1)) stop ("Cluster can not be used in an interaction")
  1028.     cluster <- strata(m[,tempc$vars], shortlabel=T)  #allow multiples
  1029.     dropx <- tempc$terms
  1030.     }
  1031.     if (length(strats)) {
  1032.     temp <- untangle.specials(Terms, 'strata', 1)
  1033.     dropx <- c(dropx, temp$terms)
  1034.     if (length(temp$vars)==1) strata.keep <- m[[temp$vars]]
  1035.     else strata.keep <- strata(m[,temp$vars], shortlabel=T)
  1036.     strats <- as.numeric(strata.keep)
  1037.     }
  1038.     if (length(dropx)){ 
  1039. ###<TSL> drop strata/cluster terms from the formula. Need to redo the model frame
  1040. ###      because R model.matrix assumes the formula and model frame correspond exactly.
  1041.       newTerms<-Terms[-dropx]
  1042.       mcopy$formula<-newTerms
  1043.       newm<-eval(mcopy,sys.parent())
  1044.       X <- model.matrix(newTerms, newm)[,-1,drop=F]
  1045. ###</TSL>
  1046.     }
  1047.     else               
  1048.       X <- model.matrix(Terms, m)[,-1,drop=F]
  1049.  
  1050.     type <- attr(Y, "type")
  1051.     if( method=="breslow" || method =="efron") {
  1052.     if (type== 'right')  fitter <- get("coxph.fit")
  1053.     else if (type=='counting') fitter <- get("agreg.fit")
  1054.     else stop(paste("Cox model doesn't support \"", type,
  1055.               "\" survival data", sep=''))
  1056.     }
  1057.     else if (method=='exact') fitter <- get("agexact.fit")
  1058.     else stop(paste ("Unknown method", method))
  1059.  
  1060.     if (missing(init)) init <- NULL
  1061.     fit <- fitter(X, Y, strats, offset, init=init, iter.max=iter.max,
  1062.             eps=eps, weights=weights,
  1063.             method=method, row.names(m))
  1064.  
  1065.     if (is.character(fit)) {
  1066.     fit <- list(fail=fit)
  1067.     attr(fit, 'class') <- 'coxph'
  1068.     }
  1069.     else {
  1070.     if (any(is.na(fit$coef))) {
  1071.        vars <- (1:length(fit$coef))[is.na(fit$coef)]
  1072.        msg <-paste("X matrix deemed to be singular; variable",
  1073.                paste(vars, collapse=" "))
  1074.        if (singular.ok) warning(msg)
  1075.        else             stop(msg)
  1076.        }
  1077.     fit$n <- nrow(Y)
  1078.     attr(fit, "class") <-  fit$method
  1079. ###<TSL> have to fix up the class of Terms, since it randomly vanishes.
  1080.     class(Terms)<-c("terms","formula")
  1081. ###</TSL>
  1082.     fit$terms <- Terms
  1083.     fit$assign <- attr(X, 'assign')
  1084.     if (robust) {
  1085.         fit$naive.var <- fit$var
  1086.         fit$method    <- method
  1087.         # a little sneaky here: by calling resid before adding the
  1088.         #   na.action method, I avoid having missings re-inserted
  1089.         # I also make sure that it doesn't have to reconstruct X and Y
  1090.         fit2 <- c(fit, list(x=X, y=Y, weights=weights))
  1091.         if (length(strats)) fit2$strata <- strata.keep
  1092.         if (length(cluster)) {
  1093.         temp <- residuals.coxph(fit2, type='dfbeta', collapse=cluster,
  1094.                       weighted=T)
  1095.         indx <- match(cluster, unique(cluster))
  1096.         k    <- as.vector(table(indx))
  1097.         if (any(k>1)) {
  1098.             #compute the ICC for the m-residuals
  1099.             N    <- sum(k * (k-1))
  1100.             mu   <- sum(fit$resid * (k-1)[indx])/N   #grand mean
  1101.             mu2  <- tapply(fit$resid, indx, mean)    # group means
  1102.             sig  <- tapply((fit$resid - mu)^2, indx, sum)  #SS
  1103.             icc1 <- sum( (k*(mu2-mu))^2 - sig) / sum((k-1)*sig)
  1104.             #rank residuals
  1105.             rr <- rank(fit$resid)
  1106.             mu   <- sum(rr * (k-1)[indx])/N   #grand mean
  1107.             mu2  <- tapply(rr, indx, mean)    # group means
  1108.             sig  <- tapply((rr - mu)^2, indx, sum)  #SS
  1109.             icc2 <- sum( (k*(mu2-mu))^2 - sig) / sum((k-1)*sig)
  1110.  
  1111.             fit$icc <- c(length(k), icc1, icc2)
  1112.             names(fit$icc) <- c("nclust", "icc(resid)",
  1113.                             "icc(rank(resid))")
  1114.             }
  1115.         }
  1116.         else temp <- residuals.coxph(fit2, type='dfbeta', weighted=T)
  1117.         fit$var <- t(temp) %*% temp
  1118.         }
  1119.     na.action <- attr(m, "na.action")
  1120.     if (length(na.action)) fit$na.action <- na.action
  1121.     if (model) fit$model <- m
  1122.     else {
  1123.         if (x)  {
  1124.         fit$x <- X
  1125.         if (length(strats)) fit$strata <- strata.keep
  1126.         }
  1127. ##<TSL>        if (y)     fit$y <- Y
  1128.         if (y) {class(Y)<-"Surv";    fit$y <- Y}
  1129. ##</TSL> (somehow it loses its class)
  1130.         }
  1131.     }
  1132.     if (!is.null(weights) && any(weights!=1)) fit$weights <- weights
  1133.  
  1134.     fit$formula <- as.vector(attr(Terms, "formula"))
  1135.     fit$call <- call
  1136.     fit$method <- method
  1137.     fit
  1138.     }
  1139.  
  1140. # SCCS @(#)format.Surv.s    4.4 07/10/96
  1141. #
  1142. # These two functions operate with the newer data.frame code, found on statlib
  1143. #   (Eventually part of S, I assume)
  1144. #
  1145. format.Surv <- function(x, ...) format(as.character.Surv(x), ...)
  1146.  
  1147. # The better definition for this is
  1148. #   "as.data.frame.Surv <- as.data.frame.model.matrix"
  1149. # but, since not everyone has installed the new data.frame software yet, this
  1150. # will fail when it can't find as.data.frame.model.matrix.
  1151. # So, for this release of survival, the function below is an exact copy of
  1152. # as.data.frame.model.matrix, as found on statlib 9/94.
  1153. #
  1154. #  Changed 5/30/95:  there is a bug in the code I copied: if there are no
  1155. #     row names then row.names == character(0), not NULL
  1156. as.data.frame.Surv <-
  1157.     function(x, row.names = NULL, optional = F)
  1158.     {
  1159.     d <- dim(x)
  1160.     nrows <- d[[1]]
  1161.     dn <- dimnames(x)
  1162.     row.names <- dn[[1]]
  1163.     value <- list(x)
  1164. #       if(!is.null(row.names)) {
  1165.     if(length(row.names)>0) {
  1166.         row.names <- as.character(row.names)
  1167.         if(length(row.names) != nrows)
  1168.             stop(paste("supplied", length(row.names), 
  1169.                 "names for a data frame with", nrows, "rows"))
  1170.     }
  1171.     else if(optional)
  1172.         row.names <- character(nrows)
  1173.     else row.names <- as.character(seq(length = nrows))
  1174.     if(!optional)
  1175.         names(value) <- deparse(substitute(x))[[1]]
  1176.     attr(value, "row.names") <- row.names
  1177.     class(value) <- "data.frame"
  1178.     value
  1179. }
  1180. #
  1181. # SCCS @(#)is.ratetable.s    4.5 04/17/96
  1182. #
  1183. is.ratetable <- function(x, verbose=F) {
  1184.     if (!verbose) {
  1185.     if (!inherits(x, 'ratetable')) return(F)
  1186.     att <- attributes(x)
  1187.     if (any(is.na(match(c("dim", "dimnames", "dimid", "factor", "cutpoints"),
  1188.                 names(att))))) return(F)
  1189.     nd <- length(att$dim)
  1190.     if (length(x) != prod(att$dim)) return(F)
  1191.     if (!(is.list(att$dimnames) && is.list(att$cutpoints)))
  1192.          return(F)
  1193.     if (length(att$dimnames)!=nd || length(att$factor)!=nd ||
  1194.              length(att$cutpoints)!=nd) return(F)
  1195.     fac <- as.numeric(att$factor)
  1196.     if (any(is.na(fac))) return(F)
  1197.     if (any(fac <0)) return(F)
  1198.     for (i in 1:nd) {
  1199.         n <- att$dim[i]
  1200.         if (length(att$dimnames[[i]]) !=n) return(F)
  1201.         if (fac[i]!=1 && length(att$cutpoints[[i]])!=n) return(F)
  1202.         if (fac[i]!=1 && any(order(att$cutpoints[[i]])!= 1:n)) return(F)
  1203.         if (fac[i]==1 && !is.null(att$cutpoints[[i]]))  return(F)
  1204.         if (fac[i]>1 && i<nd) return(F)
  1205.         }
  1206.     return(T)
  1207.     }
  1208.  
  1209.     #verbose return messages, useful for debugging
  1210.     msg <- ""
  1211.     if (!inherits(x, 'ratetable')) msg <- c(msg, "wrong class")
  1212.     att <- attributes(x)
  1213.     if (any(is.na(match(c("dim", "dimnames", "dimid", "factor", "cutpoints"),
  1214.             names(att))))) msg <- c(msg, 'missing an attribute')
  1215.     nd <- length(att$dim)
  1216.     if (length(x) != prod(att$dim)) msg <- c(msg, 'dims dont match length')
  1217.     if (!(is.list(att$dimnames) && is.list(att$cutpoints)))
  1218.          msg <- c(msg, 'dimnames or cutpoints not a list')
  1219.     if (length(att$dimnames)!=nd || length(att$factor)!=nd ||
  1220.              length(att$cutpoints)!=nd) msg <- c(msg, 'bad lengths')
  1221.     fac <- as.numeric(att$factor)
  1222.     if (any(is.na(fac))) msg <- c(msg, 'a missing factor')
  1223.     if (any(fac <0)) msg <- c(msg, 'factor <0')
  1224.     for (i in 1:nd) {
  1225.     n <- att$dim[i]
  1226.     if (length(att$dimnames[[i]]) !=n) msg <- c(msg, 'dimnames wrong length')
  1227.     if (fac[i]!=1 && length(att$cutpoints[[i]])!=n) msg <- c(msg, 'cutpnt missing')
  1228.     if (fac[i]!=1 && any(order(att$cutpoints[[i]])!= 1:n)) msg <- c(msg, 'unsorted cutpoints')
  1229.     if (fac[i]==1 && !is.null(att$cutpoints[[i]]))  msg <- c(msg, 'cutpnt should be null')
  1230.     if (fac[i]>1 && i<nd) msg <- c(msg, 'only the last dim can be interpolated')
  1231.     }
  1232.     if (msg=='') T
  1233.     else msg
  1234.     }
  1235. #
  1236. # SCCS @(#)is.ratetable.verbose.s    1.1 10/27/95
  1237. #   A version of the function that tells you WHY it's not a ratetable
  1238. #
  1239.  
  1240. is.ratetable.verbose <- function(x) {
  1241.     if (!inherits(x, 'ratetable')) return("wrong class")
  1242.     att <- attributes(x)
  1243.     if (any(is.na(match(c("dim", "dimnames", "dimid", "factor", "cutpoints"),
  1244.             names(att))))) return('missing an attribute')
  1245.     nd <- length(att$dim)
  1246.     if (length(x) != prod(att$dim)) return('dims dont match length')
  1247.     if (!(is.list(att$dimnames) && is.list(att$cutpoints)))
  1248.          return('dimnames or cutpoints not a list')
  1249.     if (length(att$dimnames)!=nd || length(att$factor)!=nd ||
  1250.              length(att$cutpoints)!=nd) return('bad lengths')
  1251.     fac <- as.numeric(att$factor)
  1252.     if (any(is.na(fac))) return('a missing factor')
  1253.     if (any(fac <0)) return('factor <0')
  1254.     for (i in 1:nd) {
  1255.     n <- att$dim[i]
  1256.     if (length(att$dimnames[[i]]) !=n) return('dimnames wrong length')
  1257.     if (fac[i]!=1 && length(att$cutpoints[[i]])!=n) return('cutpnt missing')
  1258.     if (fac[i]!=1 && any(order(att$cutpoints[[i]])!= 1:n)) return('unsorted cutpoints')
  1259.     if (fac[i]==1 && !is.null(att$cutpoints[[i]]))  return('cutpnt should be null')
  1260.     if (fac[i]>1 && i<nd) return('only the last dim can be interpolated')
  1261.     }
  1262.     T
  1263.     }
  1264. # SCCS @(#)lines.survfit.s    4.8  12/14/94
  1265. lines.survfit <- function(x, type='s', mark=3, col=1, lty=1, lwd=1,
  1266.                mark.time =T, xscale=1, yscale=1,  ...) {
  1267.     if (inherits(x, 'survexp')) {
  1268.     if (missing(type)) type <- 'l'
  1269.     if (!is.numeric(mark.time)) mark.time <- F
  1270.     }
  1271.     if (is.numeric(mark.time)) mark.time <- sort(unique(mark.time[mark.time>0]))
  1272.  
  1273.     if (is.null(x$strata)) {
  1274.     if (is.matrix(x$surv)) ncurv <- ncol(x$surv)
  1275.     else ncurve <- 1
  1276.     nstrat <- 1
  1277.     strata <- length(x$surv)/nstrat
  1278.     }
  1279.     else {
  1280.     strata <- x$strata
  1281.     nstrat <- length(strata)
  1282.     ncurve <- nstrat * length(x$surv)/ sum(strata)
  1283.     }
  1284.  
  1285.     mark <- rep(mark, length=ncurve)
  1286.     col  <- rep(col , length=ncurve)
  1287.     lty  <- rep(lty , length=ncurve)
  1288.     lwd  <- rep(lwd , length=ncurve)
  1289.     time <- rep(x$time, length=length(x$surv))
  1290.     j <- 1
  1291.     for (i in 1:ncurve) {
  1292.     n <- strata[1+(i-1)%%nstrat]
  1293.     who <- seq(from=j, length=n)
  1294.     j <-  j+n
  1295.     xx <- c(0, time[who])/xscale
  1296.     yy <- c(1, x$surv[who])*yscale
  1297.     nn <- length(xx)
  1298.     #
  1299.     # This 'whom' addition is to replace verbose horizonal sequences
  1300.     #  like (1, .2), (1.4, .2), (1.8, .2), (2.3, .2), (2.9, .2), (3, .1)
  1301.     #  with (1, .2), (3, .1) if type='s' and (1, .2), (2.9, .2), (3, .1)
  1302.     #  otherwise.  They are slow, and can smear the looks of a line type
  1303.     #
  1304.     whom <- c(match(unique(yy[-nn]), yy), nn)
  1305.     if (type!='s') whom <- sort(unique(c(whom, whom[-1]-1)))
  1306.     lines(xx[whom], yy[whom], type=type, col=col[i], lty=lty[i], lwd=lwd[i], ...)
  1307.  
  1308.     if (is.numeric(mark.time)) {
  1309.         indx <- mark.time
  1310.         for (k in seq(along=mark.time))
  1311.         indx[k] <- sum(mark.time[k] > xx)
  1312.         points(mark.time[indx<nn], yy[indx[indx<nn]],
  1313.            pch=mark[i],col=col[i], ...)
  1314.         }
  1315.     else if (mark.time==T) {
  1316.         deaths <- c(-1, x$n.event[who])
  1317.         if ( any(deaths==0))
  1318.         points(xx[deaths==0], yy[deaths==0],
  1319.                   pch=mark[i],col=col[i], ...)
  1320.         }
  1321.     }
  1322.     invisible()
  1323.     }
  1324. # SCCS @(#)match.ratetable.s    4.4 05/31/94
  1325. # Do a set of error checks on whether the ratetable() vars match the
  1326. #   actual ratetable
  1327. # This is called by pyears and survexp, but not by users
  1328. #
  1329. # Returns a subscripting vector and a call
  1330. #
  1331. match.ratetable <- function(R, ratetable) {
  1332.     attR <- attributes(R)
  1333.     attributes(R) <- attR['dim']     #other attrs get in the way later
  1334.     if (!is.ratetable(ratetable)) stop("Invalid rate table")
  1335.     dimid <- attr(ratetable, 'dimid')
  1336.     ord <- match(attR$dimnames[[2]], dimid)
  1337.     if (any(is.na(ord)))
  1338.        stop(paste("Argument '", (attR$dimnames[[2]])[is.na(ord)],
  1339.         "' in ratetable()",
  1340.         " does not match the given table of event rates", sep=''))
  1341.     nd <- length(ord)
  1342.     if (nd != length(dimid))
  1343.     stop("The ratetable() call has the wrong number of arguments")
  1344.     ord[ord] <- 1:nd   #reverse the index, so "ord" can be on the right-hand
  1345.     R <- R[,ord,drop=F]
  1346.  
  1347.     # Check out the dimensions of R --
  1348.     const <- attR[["constants"]][ord]
  1349.     call <- "ratetable["
  1350.     levlist <- attR[['levlist']][ord]
  1351.     dtemp <-dimnames(ratetable)
  1352.     efac  <- attr(ratetable, 'factor')
  1353.     for (i in (1:nd)) {
  1354.     if (const[i]) {   #user put in a constant
  1355.         temp <- match(levlist[[i]], dtemp[[i]])
  1356.         if (is.na(temp)) {
  1357.         temp <- as.numeric(levlist[[i]])
  1358.         if (is.na(temp))
  1359.                stop(paste("Invalid value in ratetable() for variable",
  1360.                  dimid[i]))
  1361.         if (efac[i]==1) {  # this level is a factor
  1362.             if (temp<=0 || temp!=floor(temp) || temp >length(dtemp[[i]]))
  1363.                stop(paste("Invalid value in ratetable() for variable",
  1364.                  dimid[i]))
  1365.             }
  1366.         else stop(paste("Invalid value in ratetable() for variable",
  1367.                     dimid[i]))
  1368.         }
  1369.         R[,i] <- temp
  1370.         call <- paste(call, temp)
  1371.         }
  1372.     else if (length(levlist[[i]]) >0) {  #factor or character variable
  1373.         if (efac[i]!=1) stop(paste("In ratetable(),", dimid[i],
  1374.                      "must be a continuous variable"))
  1375.         temp <- match(levlist[[i]], dtemp[[i]])
  1376.         if (any(is.na(temp)))
  1377.         stop(paste("Levels do not match for ratetable() variable",
  1378.                 dimid[i]))
  1379.         R[,i] <- temp[R[,i]]
  1380.         }
  1381.     else {   # ratetable() thinks it is a continuous variable
  1382.         if (efac[i]==1) {   #but it's not-- make sure it is an integer
  1383.         temp <- R[,i]
  1384.         if (any(floor(temp)!=temp) || any(temp<0) ||
  1385.                 max(temp) > length(dtemp[[i]]))
  1386.         stop(paste("In ratetable()",dimid[i],"out of range"))
  1387.         }
  1388.         }
  1389.     if (i==nd) call <- paste(call, "]")
  1390.     else       call <- paste(call, ",")
  1391.     }
  1392.  
  1393.     summ <- attr(ratetable, 'summary')
  1394.     if (is.null(summ))
  1395.      list(R= R[,!const, drop=F], call={if(any(const)) call else NULL})
  1396.     else list(R= R[,!const, drop=F], call={if(any(const)) call else NULL},
  1397.         summ=summ(R))
  1398.     }
  1399. model.frame.coxph <- function(object, ...) {
  1400.     Call <- object$call
  1401.     Call[[1]] <- as.name("model.frame")
  1402.     Call <- Call[match(c("", "formula", "data", "weights", "subset",
  1403.                "na.action"), names(Call), 0)]
  1404.     eval(Call)
  1405.     }
  1406. #SCCS 06/10/92 @(#)model.frame.default.s    4.3
  1407. # Only change -- look to options() for the default na.action
  1408. #
  1409. model.frame.default <- function(formula, data = NULL, na.action = na.fail, ...)
  1410. {
  1411.     if(missing(formula)) {
  1412.         if(!missing(data) && inherits(data, "data.frame") && length(
  1413.             attr(data, "terms")))
  1414.             return(data)
  1415.         formula <- as.formula(data)
  1416.         }
  1417.     else if(missing(data) && inherits(formula, "data.frame")) {
  1418.         if(length(attr(formula, "terms")))
  1419.             return(formula)
  1420.         data <- formula
  1421.         formula <- as.formula(data)
  1422.         }
  1423.     if(missing(na.action)) {
  1424.     if (!is.null(tj <- attr(data, "na.action")))  na.action <- tj
  1425.     else if (!is.null(tj <- options("na.action")[[1]])) na.action <- tj
  1426.     }
  1427.  
  1428. ###<TSL>    if(!inherits(formula, "terms"))
  1429. ###        formula <- terms(formula, data = data)
  1430.       formula <- terms(formula, data = data)
  1431. ###</TSL>
  1432.       dots <- substitute(list(...))
  1433. # Work around a bug in Splus 3.0 -- doesn't check that the objects are
  1434. #   all the same length.  Later fixed in Bell S.  Someday replace all of
  1435. #   this by the original, commented line below.
  1436. #   .Internal(model.frame(formula, data, na.action, dots), "model_frame")
  1437.     temp <- .Internal(model.frame(formula, data, na.action, dots), "model_frame")
  1438.     if (is.matrix(temp[[1]])) n <- nrow(temp[[1]])
  1439.     else                  n <- length(temp[[1]])
  1440.     j <- 1
  1441.     for (i in temp[-1]) {
  1442.     j <- j+1
  1443.     mat <- is.matrix(i)
  1444.     if ((mat && n!=nrow(i)) ||  (!mat && n!=length(i)))
  1445.         stop(paste("Length mismatch, term", j))
  1446.     }
  1447.     temp
  1448.     }
  1449. #SCCS 04/14/92 @(#)model.newframe.s    4.3
  1450. # This function is called if you want to get a new data frame,
  1451. #   usually for prediction.  It's main problem is to "glue" any
  1452. #   transform specific information back onto the formula, so that
  1453. #   data dependent transforms work as they used to.
  1454. # It only works if the data dependent functions are not inside another one,
  1455. #   so  sqrt(age - min(age)) is out of luck.  It also only works for those
  1456. #   transforms that support it by adding data dependent info as an attribute
  1457. #   of their output.
  1458. # If you know this isn't so, then safe=T uses a method that is much longer,
  1459. #   but is guarranteed to work, see predict.gam
  1460.  
  1461. model.newframe <- function(object, newdata, safe=F, response=F, ...) {
  1462.     if (inherits(object, 'terms'))  Terms <- object
  1463.     else {
  1464.     Terms <- object$terms
  1465.     if (!inherits(Terms, 'terms'))
  1466.         stop ("Invalid terms component of object")
  1467.     }
  1468.     offset <- attr(Terms, 'offset')
  1469.  
  1470.     # First, is newdata just a list of numbers?
  1471.     if (is.numeric(newdata)) {
  1472. ##    nvar <- length(Terms) + length(offset)
  1473.         nvar <- length(attr(Terms,"term.labels")) +length(offset)
  1474.     if (length(newdata)>1  || newdata!=floor(newdata)  || newdata<0){ #It's not just a frame number
  1475.         if (is.matrix(newdata) && ncol(newdata) == nvar)
  1476.            return(newdata)
  1477.         else if (length(newdata) == nvar)
  1478.            return(matrix(newdata,1,nvar))
  1479.         else stop("Argument \"newdata\" cannot be coerced to an appropriate model matrix")
  1480.         }
  1481.     }
  1482.  
  1483.     # newdata is a list, data frame, or frame number
  1484.     if (!safe) {
  1485.     #augment the arguments with extra parameters
  1486.       #someday
  1487.     if (!response) Terms <- delete.response(Terms)
  1488.     model.frame(Terms, newdata, ...)
  1489.     }
  1490.     else {
  1491.     #Do a safe call, by building up a brand new model frame
  1492.     Call <- object$call
  1493.     Call[[1]] <- as.name("model.frame")
  1494.     Call$formula <- terms.inner(formula(object))
  1495.    #might need to tack on the response here!
  1496.     if (response) stop("Not implimented yet for safe=T, response=T")
  1497.     Call$na.action <- function(x)  x
  1498.     Call <- Call[match(c("", "formula", "data", "subset", "na.action"),
  1499.         names(Call), 0)]
  1500.     data <- eval(Call)
  1501.     attr(data, "terms") <- NULL
  1502.     Call$subset <- NULL
  1503.     Call$data <- substitute(newdata)
  1504.     newdata <- eval(Call)
  1505.     attr(newdata, "terms") <- NULL
  1506.     d2 <- dim(newdata)
  1507.     if(d2[1] < 1)
  1508.         stop("0 rows in newdata")
  1509.     d1 <- dim(data)
  1510.     if(d1[2] != d2[2])  #newdata missing some variables
  1511.         data <- data[, names(newdata), drop = F]
  1512.     data[seq(d1[1] + 1, d1[1] + d2[1]),  ] <- newdata  #rbind the new on
  1513.     attr(data, "row.names") <- c(rep("OLD DATA",d1[1]), row.names(newdata))
  1514.     #Now compute the combined model frame, excluding the response
  1515.     na.action <- eval(object$call$na.action)
  1516.     Terms <- object$terms
  1517.     Terms <- delete.response(Terms)
  1518.     model.frame(Terms, data, na.action = na.action)
  1519.     }
  1520.     }
  1521. #SCCS 04/16/92 @(#)na.omit.s    4.4
  1522. na.omit <- function(frame)  {
  1523.     n <- length(frame)
  1524.     omit <- FALSE
  1525.     vars <- seq(length = n)
  1526.     for(j in vars) {
  1527.     x <- frame[[j]]
  1528.     if(!is.atomic(x)) next
  1529.     # variables are assumed to be either some sort of matrix, numeric or cat'y
  1530.     x <- is.na(x)
  1531.     d <- dim(x)
  1532.     if(is.null(d) || length(d) != 2)
  1533.         omit <- omit | x
  1534.     else {
  1535.         for(ii in 1:d[2])
  1536.             omit <- omit | x[, ii]
  1537.         }
  1538.     }
  1539.     xx <- frame[!omit,  , drop = F]
  1540.     if (any(omit)) {
  1541.     temp <- seq(omit)[omit]
  1542.     names(temp) <- row.names(frame)[omit]
  1543.     attr(temp, 'class') <- 'omit'
  1544.     attr(xx, "na.action") <- temp
  1545.     }
  1546.     xx
  1547.     }
  1548.  
  1549. naprint.omit <- function(x)
  1550.     paste(length(x), "deleted due to missing")
  1551.  
  1552. # Put the missing values back into a vector.
  1553. #   And be careful about the labels too.
  1554. naresid.omit <- function(omit, x) {
  1555.     if (length(omit)==0 || !is.numeric(omit))
  1556.     stop("Invalid argument for 'omit'")
  1557.  
  1558.     if (is.matrix(x)) {
  1559.     n <- nrow(x)
  1560.     keep <- rep(NA,n+ length(omit))
  1561.     keep[-omit] <- 1:n
  1562.     x <- x[keep,,drop=F]
  1563.     temp <- dimnames(x)[[1]]
  1564.     if (length(temp)) {
  1565.         temp[omit] <- names(omit)
  1566.         dimnames(x) <- list(temp, dimnames(x)[[2]])
  1567.         }
  1568.     x
  1569.     }
  1570.     else {
  1571.     n <- length(x)
  1572.     keep <- rep(NA,n+ length(omit))
  1573.     keep[-omit] <- 1:n
  1574.     x <- x[keep]
  1575.     temp <- names(x)
  1576.     if (length(temp)) {
  1577.         temp[omit] <- names(omit)
  1578.         names(x) <- temp
  1579.         }
  1580.     x
  1581.     }
  1582.     }
  1583. naprint.omit <- function(x)
  1584.     paste(length(x), "observations deleted due to missing")
  1585. naprint <- function(x, ...)
  1586.     UseMethod("naprint",x,...)
  1587.  
  1588. naprint.default <- function(...)
  1589.     return("")
  1590. #SCCS 04/14/92 @(#)naresid.omit.s    4.2
  1591. naresid.omit <- function(omit, x) {
  1592.     if (length(omit)==0 || !is.numeric(omit))
  1593.     stop("Invalid argument for 'omit'")
  1594.  
  1595.     if (is.matrix(x)) {
  1596.     n <- nrow(x)
  1597.     keep <- rep(NA,n+ length(omit))
  1598.     keep[-omit] <- 1:n
  1599.     x <- x[keep,,drop=F]
  1600.     temp <- dimnames(x)[[1]]
  1601.     if (length(temp)) {
  1602.         temp[omit] <- names(omit)
  1603.         dimnames(x) <- list(temp, dimnames(x)[[2]])
  1604.         }
  1605.     x
  1606.     }
  1607.     else {
  1608.     n <- length(x)
  1609.     keep <- rep(NA,n+ length(omit))
  1610.     keep[-omit] <- 1:n
  1611.     x <- x[keep]
  1612.     temp <- names(x)
  1613.     if (length(temp)) {
  1614.         temp[omit] <- names(omit)
  1615.         names(x) <- temp
  1616.         }
  1617.     x
  1618.     }
  1619.     }
  1620. naresid <- function(omit, ...)
  1621.     UseMethod("naresid",omit,...)
  1622.  
  1623. naresid.default <- function(omit, x)  x
  1624. #SCCS @(#)plot.cox.zph.s    4.6 08/13/96
  1625. plot.cox.zph <- function(x, resid=T, se=T, df=4, nsmo=40, var, ...) {
  1626.     xx <- x$x
  1627.     yy <- x$y
  1628.     d <- nrow(yy)
  1629.     df <- max(df)     #error proofing
  1630.     nvar <- ncol(yy)
  1631.     pred.x <- seq(from=min(xx), to=max(xx), length=nsmo)
  1632.     temp <- c(pred.x, xx)
  1633.     lmat <- ns(temp, df=df, intercept=T)
  1634.     pmat <- lmat[1:nsmo,]       # for prediction
  1635.     xmat <- lmat[-(1:nsmo),]
  1636.     qmat <- qr(xmat)
  1637.  
  1638.     if (se) {
  1639.     bk <- backsolve(qmat$qr[1:df, 1:df], diag(df))
  1640.     xtx <- bk %*% t(bk)
  1641.     seval <- d*((pmat%*% xtx) *pmat) %*% rep(1, df)
  1642.     }
  1643.  
  1644.     ylab <- paste("Beta(t) for", dimnames(yy)[[2]])
  1645.     if (missing(var)) var <- 1:nvar
  1646.     else {
  1647.     if (is.character(var)) var <- match(var, dimnames(yy)[[2]])
  1648.     if  (any(is.na(var)) || max(var)>nvar || min(var) <1)
  1649.         stop("Invalid variable requested")
  1650.     }
  1651.  
  1652.     #
  1653.     # Figure out a 'good' set of x-axis labels.  Find 8 equally spaced
  1654.     #    values on the 'transformed' axis.  Then adjust until they correspond
  1655.     #    to rounded 'true time' values.  Avoid the edges of the x axis, or
  1656.     #    approx() may give a missing value
  1657.     if (x$transform == 'log') {
  1658.     xx <- exp(xx)
  1659.     pred.x <- exp(pred.x)
  1660.     }
  1661.     else if (x$transform != 'identity') {
  1662.     xtime <- as.numeric(dimnames(yy)[[1]])
  1663.     apr1  <- approx(xx, xtime, seq(min(xx), max(xx), length=17)[2*(1:8)])
  1664.     temp <- signif(apr1$y,2)
  1665.     apr2  <- approx(xtime, xx, temp)
  1666.     xaxisval <- apr2$y
  1667.     xaxislab <- rep("",8)
  1668.     for (i in 1:8) xaxislab[i] <- format(temp[i])
  1669.     }
  1670.  
  1671.     for (i in var) {
  1672.     y <- yy[,i]
  1673.     yhat <- pmat %*% qr.coef(qmat, y)
  1674.     if (resid) yr <-range(yhat, y)
  1675.     else       yr <-range(yhat)
  1676.     if (se) {
  1677.         temp <- 2* sqrt(x$var[i,i]*seval)
  1678.         yup <- yhat + temp
  1679.         ylow<- yhat - temp
  1680.         yr <- range(yr, yup, ylow)
  1681.         }
  1682.  
  1683.     if (x$transform=='identity')
  1684.         plot(range(xx), yr, type='n', xlab="Time", ylab=ylab[i], ...)
  1685.     else if (x$transform=='log')
  1686.         plot(range(xx), yr, type='n', xlab="Time", ylab=ylab[i], log='x',
  1687.             ...)
  1688.     else {
  1689.         plot(range(xx), yr, type='n', xlab="Time", ylab=ylab[i], axes=F,...)
  1690.         axis(1, xaxisval, xaxislab)
  1691.         axis(2)
  1692.         box()
  1693.         }
  1694.     if (resid) points(xx, y)
  1695.     lines(pred.x, yhat)
  1696.     if (se) {
  1697.         lines(pred.x, yup,lty=2)
  1698.         lines(pred.x, ylow, lty=2)
  1699.         }
  1700.     }
  1701.     }
  1702. #SCCS 04/14/92 @(#)plot.coxph.s    4.2
  1703. plot.coxph <- function(fit, ...) {
  1704.     op <- par(ask=T)
  1705.     on.exit(par(op))
  1706.     yy <- (1-fit$residuals)/ fit$linear.predictors   # psuedo y
  1707.     plot(fit$linear.predictors, rank(yy))
  1708.  
  1709.     std.resid <- fit$residuals/ sqrt(predict(fit, type='expected'))
  1710.     plot(fit$linear.predictors, std.resid,
  1711.     xlab='Linear predictor', ylab='standardized residual')
  1712.  
  1713.     }
  1714. #SCCS @(#)plot.survfit.s    4.11 12/14/94
  1715. plot.survfit<- function(surv, conf.int,  mark.time=T,
  1716.          mark=3,col=1,lty=1, lwd=1, cex=1,log=F, yscale=1,
  1717.          xscale=1,
  1718.          xlab="", ylab="", xaxs='i', ...) {
  1719.  
  1720.     if (!inherits(surv, 'survfit'))
  1721.       stop("First arg must be the result of survfit")
  1722.  
  1723.     stime <- surv$time / xscale
  1724.     ssurv <- surv$surv
  1725.     if (missing(conf.int)) {
  1726.     if (is.null(surv$strata) && !is.matrix(ssurv)) conf.int <-T
  1727.     else conf.int <- F
  1728.     }
  1729.  
  1730.     if (is.null(surv$strata)) {
  1731.     nstrat <- 1
  1732.     stemp <- rep(1, length(surv$time))
  1733.     }
  1734.     else {
  1735.     nstrat <- length(surv$strata)
  1736.     stemp <- rep(1:nstrat,surv$strata)
  1737.     }
  1738.     if (is.null(surv$n.event)) mark.time <- F   #expected survival curve
  1739.  
  1740.     # set default values for missing parameters
  1741.     if (is.matrix(ssurv)) ncurve <- nstrat * ncol(ssurv)
  1742.     else                  ncurve <- nstrat
  1743.     mark <- rep(mark, length=ncurve)
  1744.     col  <- rep(col, length=ncurve)
  1745.     lty  <- rep(lty, length=ncurve)
  1746.     lwd  <- rep(lwd, length=ncurve)
  1747. ###<TSL>
  1748. ###    if (is.numeric(mark.time)) mark.time <- sort(mark.time[mark.time>0])
  1749.     if (!is.logical(mark.time) && is.numeric(mark.time)) mark.time <- sort(mark.time[mark.time>0])
  1750. ###</TSL>
  1751.     if (missing(xaxs)) temp <- 1.04*max(stime)
  1752.     else               temp <- max(stime)
  1753.     #
  1754.     # for log plots we have to be tricky about the y axis scaling
  1755.     #
  1756.     if   (log) {
  1757.         ymin <- min(.1,ssurv[!is.na(ssurv) &ssurv>0])
  1758.         ssurv[!is.na(ssurv) &ssurv==0] <- ymin
  1759.         plot(c(0, temp),
  1760.            yscale*c(.99, ymin),
  1761.            type ='n', log='y', xlab=xlab, ylab=ylab, xaxs=xaxs,...)
  1762.         }
  1763.      else
  1764.      plot(c(0, temp), yscale*c(0,1),
  1765.           type='n', xlab=xlab, ylab=ylab, xaxs=xaxs, ...)
  1766.  
  1767.     if (yscale !=1) par(usr=par("usr")/ c(1,1,yscale, yscale))
  1768.     #
  1769.     # put up the curves one by one
  1770.     #   survfit has already put them into the "right" order
  1771.     i _ 0
  1772.     xend _ NULL
  1773.     yend _ NULL
  1774.  
  1775.     #
  1776.     # The 'whom' addition is to replace verbose horizonal sequences
  1777.     #  like (1, .2), (1.4, .2), (1.8, .2), (2.3, .2), (2.9, .2), (3, .1)
  1778.     #  with (1, .2), (3, .1) -- remember that type='s'.  They are slow,
  1779.     #  and can smear the looks of a line type
  1780.     #
  1781.     for (j in unique(stemp)) {
  1782.     who _ (stemp==j)
  1783.     xx _ c(0,stime[who])
  1784.     deaths <- c(-1, surv$n.event[who])
  1785.     if (is.matrix(ssurv)) {
  1786.         for (k in 1:ncol(ssurv)) {
  1787.         i _ i+1
  1788.         yy _ c(1,ssurv[who,k])
  1789.         nn <- length(xx)
  1790.         whom <- c(match(unique(yy[-nn]), yy), nn)
  1791.         lines(xx[whom], yy[whom], lty=lty[i], col=col[i], lwd=lwd[i], type='s')
  1792.  
  1793.         if (is.numeric(mark.time)) {
  1794.             indx <- mark.time
  1795.             for (k in seq(along=mark.time))
  1796.             indx[k] <- sum(mark.time[k] > xx)
  1797.             points(mark.time[indx<nn], yy[indx[indx<nn]],
  1798.                pch=mark[i],col=col[i],cex=cex)
  1799.             }
  1800.         else if (mark.time==T && any(deaths==0))
  1801.             points(xx[deaths==0], yy[deaths==0],
  1802.                pch=mark[i],col=col[i],cex=cex)
  1803.         xend _ c(xend,max(xx))
  1804.         yend _ c(yend,min(yy))
  1805.  
  1806.         if (conf.int==T && !is.null(surv$upper)) {
  1807.             if (ncurve==1) lty[i] <- lty[i] +1
  1808.             yy _ c(1,surv$upper[who,k])
  1809.             lines(xx,yy, lty=lty[i], col=col[i], lwd=lwd[i], type='s')
  1810.             yy _ c(1,surv$lower[who,k])
  1811.             lines(xx,yy, lty=lty[i], col=col[i], lwd=lwd[i], type='s')
  1812.             }
  1813.         }
  1814.         }
  1815.  
  1816.     else {
  1817.         i <- i+1
  1818.         yy _ c(1,ssurv[who])
  1819.         nn <- length(xx)
  1820.         whom <- c(match(unique(yy[-nn]), yy), nn)
  1821.         lines(xx[whom], yy[whom], lty=lty[i], col=col[i], lwd=lwd[i], type='s')
  1822.  
  1823.         if (!is.logical(mark.time) && is.numeric(mark.time)) {
  1824.         indx <- mark.time
  1825.         for (k in seq(along=mark.time))
  1826.             indx[k] <- sum(mark.time[k] > xx)
  1827.         points(mark.time[indx<nn], yy[indx[indx<nn]],
  1828.                pch=mark[i],col=col[i],cex=cex)
  1829.         }
  1830.         else if (mark.time==T && any(deaths==0))
  1831.         points(xx[deaths==0], yy[deaths==0],
  1832.                pch=mark[i],col=col[i],cex=cex)
  1833.         xend _ c(xend,max(xx))
  1834.         yend _ c(yend,min(yy))
  1835.  
  1836.         if (conf.int==T && !is.null(surv$upper)) {
  1837.         if (ncurve==1) lty[i] <- lty[i] +1
  1838.         yy _ c(1,surv$upper[who])
  1839.         lines(xx,yy, lty=lty[i], col=col[i], lwd=lwd[i], type='s')
  1840.         yy _ c(1,surv$lower[who])
  1841.         lines(xx,yy, lty=lty[i], col=col[i], lwd=lwd[i], type='s')
  1842.         }
  1843.         }
  1844.     }
  1845.     invisible(list(x=xend, y=yend))
  1846. }
  1847.  
  1848. #SCCS 04/14/92 @(#)points.survfit.s    4.2
  1849. points.survfit <- function(object, ...) {
  1850.     if (!is.matrix(object$surv))
  1851.         points(object$time, object$surv, ...)
  1852.     else
  1853.         matpoints(object$time, object$surv, ...)
  1854.     }
  1855. #SCCS 06/29/93 @(#)predict.coxph.s    4.8
  1856. #What do I need to do predictions --
  1857. #
  1858. #linear predictor:  exists
  1859. #        +se     :  X matrix
  1860. #        +newdata:  means of old X matrix, new X matrix, new offset
  1861. #
  1862. #risk -- same as lp
  1863. #
  1864. #expected --    cumulative hazard for subject= baseline haz + time + risk
  1865. #        +se :  sqrt(expected)
  1866. #      +new  :  baseline hazard function, new time, new x, means of old X,
  1867. #                        new offset, new strata
  1868. #
  1869. #terms -- : X matrix and the means
  1870. #    +se  :  ""  + I matrix
  1871. #   +new  : new X matrix and the old means + I matrix
  1872. predict.coxph <-
  1873. function(object, newdata, type=c("lp", "risk", "expected", "terms"),
  1874.         se.fit=F,
  1875.         terms=labels.lm(object), collapse, safe=F, ...)
  1876.  
  1877.     {
  1878.     type <-match.arg(type)
  1879.     n <- object$n
  1880.     Terms <- object$terms
  1881.     strata <- attr(Terms, 'specials')$strata
  1882.     if (length(strata)) {
  1883.        temp <- untangle.specials(Terms, 'strata', 1)
  1884.        Terms2 <- Terms[-temp$terms]
  1885.        }
  1886.     else  Terms2 <- Terms
  1887.     offset <- attr(Terms, "offset")
  1888. ### <TSL> this is never used, so it doesn't matter that it doesn't work
  1889. ###    resp <- attr(Terms, "variables")[attr(Terms, "response")]
  1890.  
  1891.     if (missing(newdata)) {
  1892.     if (type=='terms' || (se.fit && (type=='lp' || type=='risk'))) {
  1893.         x <- object$x
  1894.         if (is.null(x)) {
  1895.         x <- model.matrix(Terms2, model.frame(object))[,-1,drop=F]
  1896.         }
  1897. ###        x <- sweep(x, 2, object$means)
  1898.         x<-x-object$means
  1899.         }
  1900.     else if (type=='expected') {
  1901.         y <- object$y
  1902.         if (missing(y)) {
  1903.         m <- model.frame(object)
  1904.         y <- model.extract(m, 'response')
  1905.         }
  1906.         }
  1907.     }
  1908.     else {
  1909.     if (type=='expected')
  1910.          m <- model.newframe(Terms, newdata, response=T)
  1911.     else m <- model.newframe(Terms2, newdata)
  1912.  
  1913.     x <- model.matrix(Terms2, m)[,-1,drop=F]
  1914. ###    x <- sweep(x, 2, object$means)
  1915.     x<- x -object$means
  1916.     if (length(offset)) {
  1917.         if (type=='expected') offset <- as.numeric(m[[offset]])
  1918.         else {
  1919.         offset <- attr(Terms2, 'offset')
  1920.         offset <- as.numeric(m[[offset]])
  1921.         }
  1922.         }
  1923.     else offset <- 0
  1924.     }
  1925.  
  1926.     #
  1927.     # Now, lay out the code one case at a time.
  1928.     #  There is some repetition this way, but otherwise the code just gets
  1929.     #    too complicated.
  1930.     coef <- ifelse(is.na(object$coef), 0, object$coef)
  1931.     if (type=='lp' || type=='risk') {
  1932.     if (missing(newdata)) {
  1933.         pred <- object$linear.predictors
  1934.         names(pred) <- names(object$residuals)
  1935.         }
  1936.     else                  pred <- x %*% coef  + offset
  1937.     if (se.fit) se <- sqrt(diag(x %*% object$var %*% t(x)))
  1938.  
  1939.     if (type=='risk') {
  1940.         pred <- exp(pred)
  1941.         if (se.fit) se <- se * sqrt(pred)
  1942.         }
  1943.     }
  1944.  
  1945.     else if (type=='expected') {
  1946.     if (missing(newdata)) pred <- y[,ncol(y)] - object$residual
  1947.     else  stop("Method not yet finished")
  1948.     se   <- sqrt(pred)
  1949.     }
  1950.  
  1951.     else {  #terms
  1952.     attr(x, "constant") <- rep(0, ncol(x))
  1953.     asgn <- object$assign
  1954.     terms <- match.arg(Terms2, labels.lm(object))
  1955.     asgn <- asgn[terms]
  1956.     if (se.fit) {
  1957.         temp <- Build.terms(x, coef, object$var, asgn, F)
  1958.         pred <- temp$fit
  1959.         se   <- temp$se.fit
  1960.         }
  1961.     else pred<- Build.terms(x, coef, NULL, asgn, F)
  1962.     }
  1963.  
  1964.     if (se.fit) se <- drop(se)
  1965.     pred <- drop(pred)
  1966.     #Expand out the missing values in the result
  1967.     if (!is.null(object$na.action)) {
  1968.     pred <- naresid(object$na.action, pred)
  1969.     if (is.matrix(pred)) n <- nrow(pred)
  1970.     else               n <- length(pred)
  1971.     if(se.fit) se <- naresid(object$na.action, se)
  1972.     }
  1973.  
  1974.     # Collapse over subjects, if requested
  1975.     if (!missing(collapse)) {
  1976.     if (length(collapse) != n) stop("Collapse vector is the wrong length")
  1977.     pred <- rowsum(pred, collapse)
  1978.     if (se.fit) se <- sqrt(rowsum(se^2, collapse))
  1979.     }
  1980.  
  1981.     if (se.fit) list(fit=pred, se.fit=se)
  1982.     else pred
  1983.     }
  1984. # SCCS @(#)predict.survreg.s    4.7 07/14/92
  1985. predict.survreg <-
  1986.     function(object, newdata, ...)
  1987.     {
  1988.     # This routine really hasn't been written-- you are looking at a
  1989.     #          placeholder.  Some glm aspects do work, however.
  1990.     NextMethod("predict")
  1991.     }
  1992. # SCCS @(#)print.cox.zph.s    4.5 09/27/96
  1993. print.cox.zph <- function(x, digits = max(options()$digits - 4, 3))
  1994.     invisible(print(x$table, digits=digits))
  1995. #SCCS 09/27/96 @(#)print.coxph.null.s    4.6
  1996. print.coxph.null <-
  1997.  function(cox, digits=max(options()$digits - 4, 3), ...)
  1998.     {
  1999.     if (!is.null(cl<- cox$call)) {
  2000.     cat("Call:  ")
  2001.     dput(cl)
  2002.     cat("\n")
  2003.     }
  2004.  
  2005.     cat("Null model\n  log likelihood=", format(cox$loglik), "\n")
  2006.     omit <- cox$na.action
  2007.     if (length(omit))
  2008.     cat("  n=", cox$n, " (", naprint(omit), ")\n",
  2009.                 sep="")
  2010.     else cat("  n=", cox$n, "\n")
  2011.     }
  2012. # SCCS @(#)print.coxph.s    4.8 07/10/96
  2013. print.coxph <-
  2014.  function(cox, digits=max(options()$digits - 4, 3), ...)
  2015.     {
  2016.     if (!is.null(cl<- cox$call)) {
  2017.     cat("Call:\n")
  2018.     dput(cl)
  2019.     cat("\n")
  2020.     }
  2021.     if (!is.null(cox$fail)) {
  2022.     cat(" Coxph failed.", cox$fail, "\n")
  2023.     return()
  2024.     }
  2025.     savedig <- options(digits = digits)
  2026.     on.exit(options(savedig))
  2027.  
  2028.     coef <- cox$coef
  2029.     se <- sqrt(diag(cox$var))
  2030.     if(is.null(coef) | is.null(se))
  2031.         stop("Input is not valid")
  2032.  
  2033.     if (is.null(cox$naive.var)) {
  2034.     tmp <- cbind(coef, exp(coef), se, coef/se,
  2035.            signif(1 - pchisq((coef/ se)^2, 1), digits -1))
  2036.     dimnames(tmp) <- list(names(coef), c("coef", "exp(coef)",
  2037.         "se(coef)", "z", "p"))
  2038.     }
  2039.     else {
  2040.     nse <- sqrt(diag(cox$naive.var))
  2041.     tmp <- cbind(coef, exp(coef), nse, se, coef/se,
  2042.            signif(1 - pchisq((coef/se)^2, 1), digits -1))
  2043.     dimnames(tmp) <- list(names(coef), c("coef", "exp(coef)",
  2044.         "se(coef)", "robust se", "z", "p"))
  2045.     }
  2046.     cat("\n")
  2047.     prmatrix(tmp)
  2048.  
  2049.     logtest <- -2 * (cox$loglik[1] - cox$loglik[2])
  2050.     df <- sum(!is.na(coef))
  2051.     cat("\n")
  2052.     cat("Likelihood ratio test=", format(round(logtest, 2)), "  on ",
  2053.     df, " df,", " p=", format(1 - pchisq(logtest, df)),  sep="")
  2054.     omit <- cox$na.action
  2055.     if (length(omit))
  2056.     cat("  n=", cox$n, " (", naprint(omit), ")\n", sep="")
  2057.     else cat("  n=", cox$n, "\n")
  2058.     if (length(cox$icc))
  2059.     cat("   number of clusters=", cox$icc[1],
  2060.         "    ICC=", format(cox$icc[2:3]), "\n")
  2061.     invisible()
  2062.     }
  2063. #SCCS 01/03/94 @(#)print.data.frame.s    4.4
  2064. #
  2065. # In order to get objects with attributes to print correctly, I replace the
  2066. #   call to "as.matrix" with a copy of as.matrix.data.frame, one that knows
  2067. #   its output is character, and so calls the appropriate as.character routine
  2068. #
  2069. ##<TSL> disable this by renaming - it doesn't work </TSL>
  2070. dont.print.data.frame <-
  2071. function(x, ..., quote = F, right = T)
  2072. {
  2073.     if(length(x)==0)
  2074.         cat("NULL data frame with", length(row.names(x)), "rows\n")
  2075.  
  2076.     else if(length(row.names(x))==0) {
  2077.         print.atomic(names(x), quote = F)
  2078.         cat("< 0 rows> \n")
  2079.         }
  2080.     else {
  2081.     DD <- dim(x)
  2082.     dn <- dimnames(x)
  2083.     collabs <- as.list(dn[[2]])
  2084.     class(x) <- NULL
  2085.     p <- DD[2]
  2086.     n <- DD[1]
  2087.     non.numeric <- non.atomic <- F
  2088.     for(j in 1:p) {
  2089.         xj <- x[[j]]
  2090.  
  2091.         # 4 Line below are the ones I added
  2092.         if (!is.null(cl <-class(xj)) &&
  2093.                (cl == 'Surv' || cl=='date'))
  2094.                  xj <- x[[j]] <- as.character(x[[j]])
  2095.         if(length(dj <- dim(xj)) == 2 && dj[2] > 1) {
  2096.         if (inherits(xj, "data.frame"))
  2097.             xj <- x[[j]] <- as.matrix(x[[j]])
  2098.         dnj <- dimnames(xj)[[2]]
  2099.         collabs[[j]] <- paste(collabs[[j]], if(length(dnj)) dnj
  2100.              else seq(1:dj[2]), sep = ".")
  2101.         }
  2102.         if(length(levels(xj)) > 0 || (!is.complex(xj) ||!is.numeric(xj)))
  2103.         non.numeric <- TRUE
  2104.         if(!is.atomic(xj))
  2105.         non.atomic <- TRUE
  2106.         }
  2107.     if(non.atomic) {
  2108.         for(j in 1:p) {
  2109.         xj <- x[[j]]
  2110.         if(is.recursive(xj)) {
  2111.             }
  2112.         else x[[j]] <- as.list(as.vector(xj))
  2113.         }
  2114.         }
  2115.     else if(non.numeric) {
  2116.         for(j in 1:p) {
  2117.         xj <- x[[j]]
  2118.         if(length(levels(xj)))
  2119.             x[[j]] <- as.vector(xj)
  2120.         else x[[j]] <- format(xj)
  2121.         }
  2122.         }
  2123.     x <- unlist(x, recursive = F)
  2124.     dim(x) <- c(n, length(x)/n)
  2125.     dimnames(x) <- list(dn[[1]], unlist(collabs, use.names=F))
  2126.     class(x) <- "matrix"
  2127.     print(x, ..., quote=quote, right=right)
  2128.     }
  2129.     invisible(x)
  2130.     }
  2131. #SCCS @(#)print.summary.survfit.s    4.2 09/27/96
  2132. print.summary.survfit <- function(fit, digits = max(options()$digits - 4, 3), ...) {
  2133.     savedig <- options(digits=digits)
  2134.     on.exit(options(savedig))
  2135.  
  2136.     if (!is.null(cl<- fit$call)) {
  2137.     cat("Call: ")
  2138.     dput(cl)
  2139.     cat("\n")
  2140.     }
  2141.  
  2142.     omit <- fit$na.action
  2143.     if (length(omit))
  2144.     cat(naprint(omit), "\n")
  2145.  
  2146.     mat <- cbind(fit$time, fit$n.risk, fit$n.event, fit$surv)
  2147.     cnames <- c("time", "n.risk", "n.event")
  2148.     if (is.matrix(fit$surv)) ncurve <- ncol(fit$surv)
  2149.     else ncurve <- 1
  2150.  
  2151.     if (ncurve==1) {                 #only 1 curve
  2152.     cnames <- c(cnames, "survival")
  2153.     if (!is.null(fit$std.err)) {
  2154.         if (is.null(fit$lower)) {
  2155.         mat <- cbind(mat, fit$std.err)
  2156.         cnames <- c(cnames, "std.err")
  2157.         }
  2158.         else {
  2159.         mat <- cbind(mat, fit$std.err, fit$lower, fit$upper)
  2160.         cnames <- c(cnames, 'std.err',
  2161.               paste("lower ", fit$conf.int*100, "% CI", sep=''),
  2162.               paste("upper ", fit$conf.int*100, "% CI", sep=''))
  2163.         }
  2164.         }
  2165.     }
  2166.     else cnames <- c(cnames, paste("survival", seq(ncurve), sep=''))
  2167.  
  2168.     dimnames(mat) <- list(NULL, cnames)
  2169.     if (is.null(fit$strata)) {
  2170.     prmatrix(mat, rowlab=rep("", nrow(mat)))
  2171.     }
  2172.     else  { #print it out one strata at a time
  2173.     for (i in levels(fit$strata)) {
  2174.         who <- (fit$strata==i)
  2175.         cat("               ", i, "\n")
  2176.         if (sum(who) ==1) print(mat[who,])
  2177.         else    prmatrix(mat[who,], rowlab=rep("", sum(who)))
  2178.         cat("\n")
  2179.         }
  2180.     }
  2181.     invisible(fit)
  2182.     }
  2183. # SCCS @(#)print.summary.survreg.s    4.8 09/27/96
  2184. print.summary.survreg <- function(x, digits = max(options()$digits - 4, 3), quote = T, prefix = "")
  2185. {
  2186.     nas <- x$nas
  2187.     coef <- x$coef
  2188.     correl <- x$correl
  2189.     if(any(nas)) {
  2190.         nc <- length(nas)
  2191.         cnames <- names(nas)
  2192.         coef1 <- array(NA, c(nc, 3), list(cnames, dimnames(coef)[[2]]))
  2193.             
  2194.         coef1[!nas,  ] <- coef
  2195.         coef <- coef1
  2196.         if(!is.null(correl)) {
  2197.             correl1 <- matrix(NA, nc, nc, dimnames = list(cnames,
  2198.                 cnames))
  2199.             correl1[!nas, !nas] <- correl
  2200.             correl <- correl1
  2201.             }
  2202.         }
  2203.     if(is.null(digits))
  2204.         digits <- options()$digits
  2205.     else options(digits = digits)
  2206.     cat("\nCall:\n")
  2207.     dput(x$call)
  2208.     dresid <- x$deviance.resid
  2209.     n <- length(dresid)
  2210.     rdf <- x$df[2]
  2211.     if(rdf > 5) {
  2212.         cat("Deviance Residuals:\n")
  2213.         rq <- quantile(as.vector(dresid))
  2214.         names(rq) <- c("Min", "1Q", "Median", "3Q", "Max")
  2215.         print(rq, digits = digits)
  2216.         }
  2217.     else if(rdf > 0) {
  2218.         cat("Deviance Residuals:\n")
  2219.         print(dresid, digits = digits)
  2220.         }
  2221.     if(any(nas))
  2222.         cat("\nCoefficients: (", sum(nas), 
  2223.             " not defined because of singularities)\n", sep = "")
  2224.         
  2225.     else cat("\nCoefficients:\n")
  2226.     print(coef, digits = digits)
  2227.     omit <- x$na.action
  2228.     if (length(omit))
  2229.     cat("  n=", n, " (", naprint(omit), ")\n", sep="")
  2230.  
  2231.     cat("\n", x$parms, "\n", sep='')
  2232.     int <- attr(x$terms, "intercept")
  2233.     if(is.null(int))
  2234.         int <- 1
  2235.     temp <- format(round(c(x$null.deviance, x$deviance), digits))
  2236.     cat("\n    Null Deviance:", temp[1], "on",
  2237.              n - int, "degrees of freedom\n")
  2238.     cat("Residual Deviance:", temp[2], "on",
  2239.        round(rdf, digits), "degrees of freedom  (LL=",
  2240.         format(x$loglik), ")\n")
  2241.     cat("Number of Newton-Raphson Iterations:", format(trunc(x$iter)),
  2242.         "\n")
  2243.     if(!is.null(correl)) {
  2244.         p <- dim(correl)[2]
  2245.         if(p > 1) {
  2246.             cat("\nCorrelation of Coefficients:\n")
  2247.             ll <- lower.tri(correl)
  2248.             correl[ll] <- format(round(correl[ll], digits))
  2249.             correl[!ll] <- ""
  2250.             print(correl[-1,  - p, drop = F], quote = F, digits = 
  2251.                 digits)
  2252.             }
  2253.         }
  2254.     cat("\n")
  2255.     invisible(NULL)
  2256.     }
  2257. #SCCS 09/27/96 @(#)print.survdiff.s    4.10
  2258. print.survdiff <- function(fit, digits = max(options()$digits - 4, 3), ...) {
  2259.  
  2260.     saveopt <-options(digits=digits)
  2261.     on.exit(options(saveopt))
  2262.  
  2263.     if (!inherits(fit, 'survdiff'))
  2264.     stop("Object is not the result of survdiff")
  2265.     if (!is.null(cl<- fit$call)) {
  2266.     cat("Call:\n")
  2267.     dput(cl)
  2268.     cat("\n")
  2269.     }
  2270.  
  2271.     omit <- fit$na.action
  2272.     if (length(omit)) cat("n=", sum(fit$n), ", ", naprint(omit),
  2273.                       ".\n\n", sep='')
  2274.  
  2275.     if (length(fit$n)==1)  {
  2276.     z <- sign(fit$exp - fit$obs) * sqrt(fit$chisq)
  2277.     temp <- c(fit$obs, fit$exp, z, signif(1-pchisq(fit$chisq, 1),digits))
  2278.     names(temp) <- c("Observed", "Expected", "Z", "p")
  2279.     print(temp)
  2280.     }
  2281.     else {
  2282.     if (is.matrix(fit$obs)){
  2283.         otmp <- apply(fit$obs,1,sum)
  2284.         etmp <- apply(fit$exp,1,sum)
  2285.         }
  2286.     else {
  2287.         otmp <- fit$obs
  2288.         etmp <- fit$exp
  2289.         }
  2290.     df <- (sum(1*(etmp>0))) -1
  2291. ##    temp <- cbind(fit$n, otmp, etmp, ((otmp-etmp)^2)/ etmp,((otmp-etmp)^2)/ diag(fit$var))
  2292. ##    dimnames(temp) <- list(names(fit$n), c("N", "Observed", "Expected","(O-E)^2/E", "(O-E)^2/V"))
  2293.     temp <- cbind(as.vector(fit$n), otmp, etmp, ((otmp - etmp)^2)/etmp, ((otmp - etmp)^2)/diag(fit$var))
  2294.     dimnames(temp) <- list(rownames(fit$n), c("N", "Observed", "Expected", "(O-E)^2/E", "(O-E)^2/V"))
  2295.     print(temp)
  2296.     cat("\n Chisq=", format(round(fit$chisq,1)),
  2297.          " on", df, "degrees of freedom, p=",
  2298.          format(signif(1-pchisq(fit$chisq, df),digits)), "\n")
  2299.        }
  2300.     invisible(fit)
  2301.     }
  2302. #SCCS @(#)print.survexp.s    4.11 09/27/96
  2303. print.survexp <- function(fit, scale=1, digits = max(options()$digits - 4, 3), naprint=F, ...) {
  2304.     if (!inherits(fit, 'survexp'))
  2305.         stop("Invalid data")
  2306.     savedig <- options(digits=digits)
  2307.     on.exit(options(savedig))
  2308.  
  2309.     if (!is.null(cl<- fit$call)) {
  2310.     cat("Call:\n")
  2311.     dput(cl)
  2312.     cat("\n")
  2313.     }
  2314.  
  2315.     if (!is.null(fit$summ)) cat(fit$summ)
  2316.     omit <- fit$na.action
  2317.     if (length(omit))
  2318.     cat(naprint(omit), "\n")
  2319.     else cat("\n")
  2320.  
  2321.     if (is.null(fit$strata))  { #print it as a matrix
  2322.     mat <- cbind(fit$time/scale, fit$n.risk, fit$surv, fit$std.err)
  2323.     if (!naprint) {
  2324.         miss <- (is.na(mat)) %*% rep(1,ncol(mat))
  2325.         mat <- mat[miss<(ncol(mat)-2),,drop=F]
  2326.         }
  2327.     if (is.matrix(fit$surv)) cname <- dimnames(fit$surv)[[2]]
  2328.     else                     cname <- "survival"
  2329.     if (!is.null(fit$std.err))
  2330.           cname <- c(cname, paste("se(", cname, ")", sep=''))
  2331.     prmatrix(mat, rowlab=rep("", nrow(mat)),
  2332.            collab=c("Time", "n.risk", cname))
  2333.     }
  2334.     else  { #print it out one strata at a time, since n's differ
  2335.     if (is.null(fit$std.err)) tname <- 'survival'
  2336.     else                      tname <- c('survival', 'se(surv)')
  2337.     nstrat <- length(fit$strata)
  2338.     levs <- names(fit$strata)
  2339.     if (nrow(fit$surv)==1) {
  2340.         mat <- cbind(c(fit$n.risk), c(fit$surv), c(fit$std.err*fit$surv))
  2341.         dimnames(mat) <- list(levs, c("n.risk", tname))
  2342.         cat(" Survival at time", fit$time, "\n")
  2343.         prmatrix(mat)
  2344.         }
  2345.     else {
  2346.         for (i in 1:nstrat) {
  2347.         cat("       ", levs[i], "\n")
  2348.         mat <- cbind(fit$time/scale, fit$n.risk[,i], fit$surv[,i])
  2349.         if (!is.null(fit$std.err)) mat<- cbind(mat,
  2350.                fit$std.err[,i] * fit$surv[,i])
  2351.         if (!naprint) mat <- mat[!is.na(mat[,3]),,drop=F]
  2352.         prmatrix(mat, rowlab=rep("",nrow(mat)),
  2353.                 collab=c("Time", "n.risk", tname))
  2354.         cat("\n")
  2355.         }
  2356.         }
  2357.     }
  2358.     invisible(fit)
  2359.     }
  2360. #SCCS 09/27/96 @(#)print.survfit.s    4.8
  2361. print.survfit <- function(fit, scale=1, digits = max(options()$digits - 4, 3), ...) {
  2362.  
  2363.     if (!is.null(cl<- fit$call)) {
  2364.     cat("Call: ")
  2365.     dput(cl)
  2366.     cat("\n")
  2367.     }
  2368.     omit <- fit$na.action
  2369.     if (length(omit)) cat("  ", naprint(omit), "\n")
  2370.  
  2371.     savedig <- options(digits=digits)
  2372.     on.exit(options(savedig))
  2373.     pfun <- function(stime, surv, n.risk, n.event, lower, upper) {
  2374.     #compute the mean, median, se(mean), and ci(median)
  2375.     minmin <- function(y, x) {
  2376.          if (any(!is.na(y) & y==.5)) {
  2377.            if (any(!is.na(y) & y <.5))
  2378.          .5*( min(x[!is.na(y) & y==.5]) + min(x[!is.na(y) & y<.5]))
  2379.            else
  2380.          .5*( min(x[!is.na(y) & y==.5]) + max(x[!is.na(y) & y==.5]))
  2381.            }
  2382.          else  min(x[!is.na(y) & y<=.5])
  2383.          }
  2384.     n <- length(stime)
  2385.     hh <- c(n.event[-n]/(n.risk[-n]*(n.risk[-n]-n.event[-n])), 0)
  2386.     nused <- n.risk[1]
  2387.     ndead<- sum(n.event)
  2388.     dif.time <- c(diff(c(0, stime)), 0)
  2389.     if (is.matrix(surv)) {
  2390.         n <- nrow(surv)
  2391.         mean <- dif.time * rbind(1, surv)
  2392.         temp <- (apply(mean[(n+1):2,,drop=F], 2, cumsum))[n:1,,drop=F]
  2393.         varmean <- c(hh %*% temp^2)
  2394.         med <- apply(surv, 2, minmin, stime)
  2395.         if (!is.null(upper)) {
  2396.         upper <- apply(upper, 2, minmin, stime)
  2397.         lower <- apply(lower, 2, minmin, stime)
  2398.         cbind(nused, ndead, apply(mean, 2, sum),
  2399.               sqrt(varmean), med, lower, upper)
  2400.         }
  2401.         else {
  2402.         cbind(nused, ndead, apply(mean, 2, sum),
  2403.                sqrt(varmean), med)
  2404.         }
  2405.         }
  2406.     else {
  2407.         mean <- dif.time*c(1, surv)
  2408.         varmean <- sum(rev(cumsum(rev(mean))^2)[-1] * hh)
  2409.         med <- minmin(surv, stime)
  2410.         if (!is.null(upper)) {
  2411.         upper <- minmin(upper, stime)
  2412.         lower <- minmin(lower, stime)
  2413.         c(nused, ndead, sum(mean), sqrt(varmean), med, lower, upper)
  2414.         }
  2415.         else {
  2416.         c(nused, ndead, sum(mean), sqrt(varmean), med)
  2417.         }
  2418.         }
  2419.     }
  2420.  
  2421.     stime <- fit$time/scale
  2422.     surv <- fit$surv
  2423.     plab <- c("n", "events", "mean", "se(mean)", "median")
  2424.     if (!is.null(fit$conf.int))
  2425.     plab2<- paste(fit$conf.int, c("CI", "CI"), sep='')
  2426.  
  2427.     #Four cases: strata Y/N  by  ncol(surv)>1 Y/N
  2428.     #  Repeat the code, with minor variations, for each one
  2429.     if (is.null(fit$strata)) {
  2430.     x <- pfun(stime, surv, fit$n.risk, fit$n.event, fit$lower, fit$upper)
  2431.     if (is.matrix(x)) {
  2432.         if (is.null(fit$lower)) dimnames(x) <- list(NULL, plab)
  2433.         else                    dimnames(x) <- list(NULL, c(plab, plab2))
  2434.         }
  2435.     else {
  2436.         if (is.null(fit$lower)) names(x) <- plab
  2437.         else                    names(x) <- c(plab, plab2)
  2438.         }
  2439.     print(x)
  2440.     }
  2441.     else {   #strata case
  2442.     nstrat <- length(fit$strata)
  2443.     stemp <- rep(1:nstrat,fit$strata)
  2444.     x <- NULL
  2445.     for (i in unique(stemp)) {
  2446.         who <- (stemp==i)
  2447.         if (is.matrix(surv)) {
  2448.         temp <- pfun(stime[who], surv[who,,drop=F],
  2449.               fit$n.risk[who], fit$n.event[who],
  2450.               fit$lower[who,,drop=F], fit$upper[who,,drop=F])
  2451.         x <- rbind(x, temp)
  2452.         }
  2453.         else  {
  2454.         temp <- pfun(stime[who], surv[who], fit$n.risk[who],
  2455.               fit$n.event[who], fit$lower[who], fit$upper[who])
  2456.         x <- rbind(x, temp)
  2457.         }
  2458.         }
  2459.     temp <- names(fit$strata)
  2460.     if (nrow(x) > length(temp)) {
  2461.         nrep <- nrow(x)/length(temp)
  2462.         temp <- rep(temp, rep(nrep, length(temp)))
  2463.         }
  2464.     if (is.null(fit$lower)) dimnames(x) <- list(temp, plab)
  2465.     else                    dimnames(x) <- list(temp, c(plab, plab2))
  2466.     print(x)
  2467.     }
  2468.     invisible(fit)
  2469.     }
  2470. #SCCS @(#)print.survreg.s    4.8 11/19/92
  2471. print.survreg <- function(x, ...)
  2472. {
  2473.     if(!is.null(cl <- x$call)) {
  2474.         cat("Call:\n")
  2475.         dput(cl)
  2476.         }
  2477.     if (!is.null(x$fail)) {
  2478.     cat(" Survreg failed.", x$fail, "\n")
  2479.     return(invisible(x))
  2480.     }
  2481.     coef <- c(x$coef, x$parms[!x$fixed])
  2482.     if(any(nas <- is.na(coef))) {
  2483.     if(is.null(names(coef))) names(coef) <- paste("b", 1:length(coef), sep = "")
  2484.         cat("\nCoefficients: (", sum(nas), 
  2485.             " not defined because of singularities)\n", sep = "")
  2486.         }
  2487.     else cat("\nCoefficients:\n")
  2488.     print(coef, ...)
  2489.     rank <- x$rank
  2490.     if(is.null(rank))
  2491.         rank <- sum(!nas)
  2492.     nobs <- length(x$residuals)
  2493.     rdf <- x$df.resid
  2494.     if(is.null(rdf))
  2495.         rdf <- nobs - rank
  2496.     omit <- x$na.action
  2497.     if (length(omit))
  2498.     cat("n=", nobs, " (", naprint(omit), ")\n", sep="")
  2499. ##    sd <- survreg.distributions[[x$family[1]]]
  2500.     sd <- survreg.distributions[[x$family[1]$name]]
  2501.     cat("\n", sd$print(x$parms, x$fixed), "\n", sep='')
  2502.     cat("Degrees of Freedom:", nobs, "Total;", rdf, "Residual\n")
  2503.     cat("Residual Deviance:", format(x$deviance), "\n")
  2504.     invisible(x)
  2505.     }
  2506. #SCCS  @(#)pyears.s    4.4 07/29/96
  2507. pyears <- function(formula=formula(data), data=sys.parent(),
  2508.     weights, subset, na.action,
  2509.     ratetable=survexp.us, scale=365.25,  expected=c('event', 'pyears'),
  2510.     model=F, x=F, y=F) {
  2511.  
  2512.     expect <- match.arg(expect)
  2513.     call <- match.call()
  2514.     m <- match.call(expand=F)
  2515.     m$ratetable <- m$model <- m$x <- m$y <- m$scale<- NULL
  2516. ###<TSL>
  2517. ###    Terms <- if(missing(data)) terms(formula, 'ratetable')
  2518. ###         else              terms(formula, 'ratetable',data=data)
  2519.     Terms <-terms(formula, 'ratetable')
  2520. ### </TSL>
  2521.     if (any(attr(Terms, 'order') >1))
  2522.         stop("Pyears cannot have interaction terms")
  2523.     m$formula <- Terms
  2524.     m[[1]] <- as.name("model.frame")
  2525.     m <- eval(m, sys.parent())
  2526.  
  2527.     Y <- model.extract(m, 'response')
  2528.     if (is.null(Y)) stop ("Follow-up time must appear in the formula")
  2529.     if (!is.Surv(Y)){
  2530.     if (any(Y <0)) stop ("Negative follow up time")
  2531.     Y <- as.matrix(Y)
  2532.     if (ncol(Y) >2) stop("Y has too many columns")
  2533.     if (ncol(Y)==2 && any(Y[,2] <= Y[,1]))
  2534.         stop("stop time must be > start time")
  2535.     }
  2536.     n <- nrow(Y)
  2537.  
  2538.     weights <- model.extract(m, 'weights')
  2539.  
  2540.     rate <- attr(Terms, "specials")$ratetable
  2541.     if (length(rate) >1 )
  2542.     stop ("Can have only 1 ratetable() call in a formula")
  2543.     else if (length(rate)==1) {
  2544.     ovars <- (dimnames(attr(Terms, 'factors'))[[1]])[-c(1, rate)]
  2545.     rtemp <- match.ratetable(m[,rate], ratetable)
  2546.     R <- rtemp$R
  2547.     if (!is.null(rtemp$call)) {  #need to drop some dimensions from ratetable
  2548.         ratetable <- eval(parse(text=temp$call))
  2549.         }
  2550.     }
  2551.     else {
  2552.     ovars <- (dimnames(attr(Terms, 'factors'))[[1]])[-1]
  2553.     }
  2554.  
  2555.     # Now process the other (non-ratetable) variables
  2556.     if (length(ovars)==0)  {
  2557.     # no categories!
  2558.     X <- rep(1,n)
  2559.     ofac <- odim <- odims <- ocut <- 1
  2560.     }
  2561.     else {
  2562.     odim <- length(ovars)
  2563.     ocut <- NULL
  2564.     odims <- ofac <- double(odim)
  2565.     X <- matrix(0, n, odim)
  2566.     outdname <- vector("list", odim)
  2567.     for (i in 1:odim) {
  2568.         temp <- m[[ovars[i]]]
  2569.         ctemp <- class(temp)
  2570.         if (!is.null(ctemp) && ctemp=='tcut') {
  2571.         X[,i] <- temp
  2572.         temp2 <- attr(temp, 'cutpoints')
  2573.         odims[i] <- length(temp2) -1
  2574.         ocut <- c(ocut, temp2)
  2575.         ofac[i] <- 0
  2576.         outdname[[i]] <- attr(temp, 'labels')
  2577.         }
  2578.         else {
  2579.         temp2 <- factor(temp)
  2580.         X[,i] <- temp2
  2581.         temp3 <- levels(temp2)
  2582.         odims[i] <- length(temp3)
  2583.         ofac[i] <- 1
  2584.         outdname[[i]] <- temp3
  2585.         }
  2586.         }
  2587.     }
  2588.  
  2589.     # Now do the computations
  2590.     ocut <-c(ocut,0)   #just in case it were of length 0
  2591.     osize <- prod(odims)
  2592.     if (length(rate)) {  #include expected
  2593.     atts <- attributes(ratetable)
  2594.     cuts <- atts$cutpoints
  2595.     rfac <- atts$factor
  2596.     us.special <- (rfac >1)
  2597.     if (any(us.special)) {  #special handling for US pop tables
  2598.         if (sum(us.special) >1)
  2599.         stop("Two columns marked for special handling as a US rate table")
  2600.         #slide entry date so that it appears that they were born on Jan 1
  2601.         cols <- match(c("age", "year"), atts$dimid)
  2602.         if (any(is.na(cols))) stop("Ratetable does not have expected shape")
  2603.         temp <- date.mdy(R[,cols[2]]-R[,cols[1]])
  2604.         R[,cols[2]] <- R[,cols[2]] - mdy.date(temp$month, temp$day, 1960)
  2605.         # Doctor up "cutpoints"
  2606.         temp <- (1:length(rfac))[us.special]
  2607.         nyear <- length(cuts[[temp]])
  2608.         nint <- rfac[temp]       #intervals to interpolate over
  2609.         cuts[[temp]] <- round(approx(nint*(1:nyear), cuts[[temp]],
  2610.                         nint:(nint*nyear))$y - .0001)
  2611.         }
  2612.  
  2613.     temp <- .C("pyears1",
  2614.             as.integer(n),
  2615.             as.integer(ncol(Y)),
  2616.             as.integer(is.Surv(Y)),
  2617.             as.double(Y),
  2618.             as.integer(length(atts$dim)),
  2619.             as.integer(rfac),
  2620.             as.integer(atts$dim),
  2621.             as.double(unlist(cuts)),
  2622.             ratetable,
  2623.             as.double(R),
  2624.             as.integer(odim),
  2625.             as.integer(ofac),
  2626.             as.integer(odims),
  2627.             as.double(ocut),
  2628.             as.integer(expect=='event'),
  2629.             X,
  2630.             pyears=double(osize),
  2631.             pn    =double(osize),
  2632.             pcount=double(if(is.Surv(Y)) osize else 1),
  2633.             pexpect=double(osize),
  2634.             offtable=double(1))[17:21]
  2635.     }
  2636.     else {
  2637.     temp <- .C('pyears2',
  2638.             as.integer(n),
  2639.             as.integer(ncol(Y)),
  2640.             as.integer(is.Surv(Y)),
  2641.             as.double(Y),
  2642.             as.integer(odim),
  2643.             as.integer(ofac),
  2644.             as.integer(odims),
  2645.             as.double(ocut),
  2646.             X,
  2647.             pyears=double(osize),
  2648.             pn    =double(osize),
  2649.             pcount=double(if(is.Surv(Y)) osize else 1),
  2650.             offtable=double(1)) [10:13]
  2651.     }
  2652.  
  2653.     out <- list(call = call,
  2654.         pyears= array(temp$pyears/scale, dim=odims, dimnames=outdname),
  2655.         n     = array(temp$pn,     dim=odims, dimnames=outdname),
  2656.         offtable = temp$offtable/scale)
  2657.     if (length(rate)) {
  2658.         out$expected <- array(temp$pexpect, dim=odims, dimnames=outdname)
  2659.     if (expect=='pyears') out$expected <- out$expected/scale
  2660.     if (!is.null(rtemp$summ)) out$summary <- rtemp$summ
  2661.     }
  2662.     if (is.Surv(Y))
  2663.     out$event    <- array(temp$pcount, dim=odims, dimnames=outdname)
  2664.     na.action <- attr(m, "na.action")
  2665.     if (length(na.action))  out$na.action <- na.action
  2666.     if (model) out$model <- m
  2667.     else {
  2668.     if (x) out$x <- cbind(X, R)
  2669.     if (y) out$y <- Y
  2670.     }
  2671.     class(out) <- 'pyears'
  2672.     out
  2673.     }
  2674.  
  2675. #SCCS @(#)ratetable.s    4.9 01/31/95
  2676. #
  2677. # This is a 'specials' function for pyears
  2678. #   it is a stripped down version of as.matrix(data.frame(...))
  2679. # There is no function to create a ratetable.
  2680. # This function has a class, only so that data frame subscripting will work
  2681. #
  2682. ratetable <- function(...) {
  2683.     args <- list(...)
  2684.     nargs <- length(args)
  2685.     ll <- 1:nargs
  2686.     for (i in ll) ll[i] <- length(args[[i]])
  2687.     n <- max(ll)
  2688.     levlist <- vector("list", nargs)
  2689.     x <- matrix(0,n,nargs)
  2690.     dimnames(x) <- list(1:n, names(args))
  2691.     for (i in 1:nargs) {
  2692.     if (ll[i] ==n) {
  2693.         if (!is.numeric(args[[i]])) args[[i]] <- factor(args[[i]])
  2694.         if (is.factor(args[[i]])) {
  2695.         levlist[[i]] <- levels(args[[i]])
  2696.         x[,i] <- c(args[[i]])
  2697.         }
  2698.         else x[,i] <- args[[i]]
  2699.         }
  2700.     else if (ll[i] ==1) levlist[i] <- args[i]
  2701.     else stop("All arguments to ratetable() must be the same length")
  2702.     }
  2703.     attr(x, "constants") <- (ll==1) & (n>1)
  2704.     attr(x, "levlist")   <- levlist
  2705.     attr(x, "class")  <- "ratetable2"
  2706.     x
  2707.     }
  2708.  
  2709. # The two functions below should only be called internally, when missing
  2710. #   values cause model.frame to drop some rows
  2711. is.na.ratetable2 <- function(x) {
  2712.     attributes(x) <- list(dim=dim(x))
  2713.     as.vector((1 * is.na(x)) %*% rep(1, ncol(x)) >0)
  2714.     }
  2715. "[.ratetable2" <- function(x, rows, cols, drop=F) {
  2716.     if (!missing(cols)) {
  2717.        stop("This should never be called!")
  2718.        }
  2719.     aa <- attributes(x)
  2720.     attributes(x) <- aa[c("dim", "dimnames")]
  2721.     y <- x[rows,,drop=F]
  2722.     attr(y,'constants') <- aa$constants
  2723.     attr(y,'levlist')   <- aa$levlist
  2724.     class(y) <- aa$class
  2725.     y
  2726.     }
  2727.  
  2728. #
  2729. # Functions to manipulate rate tables
  2730. #
  2731.  
  2732. "[.ratetable" <- function(x, ..., drop=T) {
  2733.     aa <- attributes(x)
  2734.     attributes(x) <- aa[c("dim", "dimnames")]
  2735. ## <TSL>
  2736. ##    y <- NextMethod("[",x,  drop=F)
  2737.     qq<-match.call()
  2738.     qq[[1]]<-as.name("[")
  2739.     qq[[2]]<-x
  2740.     if (!missing(drop)) {qq[[length(qq)]]<-FALSE
  2741.     }else {qq$drop<-FALSE}
  2742.     y<-eval(qq)
  2743. ## </TSL>
  2744.     newdim <- attr(y, 'dim')
  2745.     if (is.null(newdim)) stop("Invalid subscript")
  2746.     dropped <- (newdim==1)
  2747.     if (drop)  change <- (newdim!=aa$dim & !dropped)
  2748.     else       change <- (newdim!=aa$dim)
  2749.  
  2750.     if (any(change)) {  #dims that got smaller, but not dropped
  2751.     newcut <- aa$cutpoints
  2752.     for (i in (1:length(change))[change])
  2753.         if (!is.null(newcut[[i]])) newcut[[i]] <-
  2754.         (newcut[[i]])[match(dimnames(y)[[i]], aa$dimnames[[i]])]
  2755.     aa$cutpoints <- newcut
  2756.     }
  2757.     if (drop && any(dropped)){
  2758.     if (all(dropped)) as.numeric(y)   #single element
  2759.     else {
  2760.         #Note that we have to drop the summary function
  2761.         attributes(y) <- list( dim = dim(y)[!dropped],
  2762.                    dimnames = dimnames(y)[!dropped],
  2763.                    dimid = aa$dimid[!dropped],
  2764.                    factor = aa$factor[!dropped],
  2765.                    cutpoints =aa$cutpoints[!dropped],
  2766.                    class = aa$class)
  2767.         y
  2768.         }
  2769.     }
  2770.     else {
  2771.     aa$dim <- aa$dimnames <- NULL
  2772.     attributes(y) <- c(attributes(y), aa)
  2773.     y
  2774.     }
  2775.     }
  2776.  
  2777. is.na.ratetable  <- function(x)
  2778.     structure(is.na(as.vector(x)), dim=dim(x), dimnames=dimnames(x))
  2779.  
  2780. Math.ratetable <- function(x, ...) {
  2781.     attributes(x) <- attributes(x)[c("dim", "dimnames")]
  2782.     NextMethod(.Generic)
  2783.     }
  2784.  
  2785. Ops.ratetable <- function(e1, e2) {
  2786.     #just treat it as an array
  2787.     if (nchar(.Method[1])) attributes(e1) <- attributes(e1)[c("dim","dimnames")]
  2788.     if (nchar(.Method[2])) attributes(e2) <- attributes(e2)[c("dim","dimnames")]
  2789.     NextMethod(.Generic)
  2790.     }
  2791.  
  2792. as.matrix.ratetable <- function(x) {
  2793.     attributes(x) <- attributes(x)[c("dim", "dimnames")]
  2794.     x
  2795.     }
  2796.  
  2797. print.ratetable <- function(x, ...)  {
  2798.     cat ("Rate table with dimension(s):", attr(x, 'dimid'), "\n")
  2799.     attributes(x) <- attributes(x)[c("dim", "dimnames")]
  2800. ### <TSL>
  2801. ###    NextMethod("print")
  2802.     print(x)
  2803. ### </TSL>
  2804.     }
  2805. #SCCS 04/14/92 @(#)residuals.coxph.null.s    4.2
  2806. residuals.coxph.null <-
  2807.   function(object, type=c("martingale", "deviance", "score", "schoenfeld"),
  2808.         ...)
  2809.     {
  2810.     type <- match.arg(type)
  2811.     if (type=='martingale' || type=='deviance') NextMethod("residuals",object)
  2812.     else stop(paste("\'", type, "\' residuals are not defined for a null model",
  2813.             sep=""))
  2814.     }
  2815. # SCCS @(#)residuals.coxph.s    4.26 11/09/95
  2816. residuals.coxph <-
  2817.   function(object, type=c("martingale", "deviance", "score", "schoenfeld",
  2818.               "dfbeta", "dfbetas", "scaledsch"),
  2819.         collapse=F, weighted=F)
  2820.     {
  2821. ###    type <- match.arg(type)
  2822.     type <- match.arg(type,c("martingale", "deviance", "score", "schoenfeld","dfbeta", "dfbetas", "scaledsch"))
  2823.     otype <- type
  2824.     if (type=='dfbeta' || type=='dfbetas') type <- 'score'
  2825.     if (type=='scaledsch') type<-'schoenfeld'
  2826.     n <- length(object$residuals)
  2827.     rr <- object$residual
  2828.     y <- object$y
  2829.     x <- object$x
  2830.     vv <- object$naive.var
  2831.     if (is.null(vv)) vv <- object$var
  2832.     weights <- object$weights
  2833.     strat <- object$strata
  2834.     method <- object$method
  2835.     if (method=='exact' && (type=='score' || type=='schoenfeld'))
  2836.     stop(paste(type, 'residuals are not available for the exact method'))
  2837.  
  2838.     if (type == 'martingale') rr <- object$residual
  2839.     else {
  2840.     # I need Y, and perhaps the X matrix (and strata)
  2841.     Terms <- object$terms
  2842.     if (!inherits(Terms, 'terms'))
  2843.         stop("invalid terms component of object")
  2844.     strats <- attr(Terms, "specials")$strata
  2845.     if (is.null(y)  ||  (is.null(x) && type!= 'deviance')) {
  2846.         temp <- coxph.getdata(object, y=T, x=T, strata=T)
  2847.         y <- temp$y
  2848.         x <- temp$x
  2849.         if (length(strats)!=0) strat <- temp$strata
  2850.         }
  2851.  
  2852.     ny <- ncol(y)
  2853.     status <- y[,ny,drop=T]
  2854.  
  2855.     if (type != 'deviance') {
  2856.         nstrat <- as.numeric(strat)
  2857.         nvar <- ncol(x)
  2858.         if (is.null(strat)) {
  2859.         ord <- order(y[,ny-1], -status)
  2860.         newstrat <- rep(0,n)
  2861.         }
  2862.         else {
  2863.         ord <- order(nstrat, y[,ny-1], -status)
  2864.         newstrat <- c(diff(as.numeric(nstrat[ord]))!=0 ,1)
  2865.         }
  2866.         newstrat[n] <- 1
  2867.  
  2868.         # sort the data
  2869.         x <- x[ord,]
  2870.         y <- y[ord,]
  2871.         score <- exp(object$linear.predictor)[ord]
  2872.         if (is.null(weights)) {weights <- rep(1,n); weighted <- F}
  2873.         else                  weights <- weights[ord]
  2874.         }
  2875.     }
  2876.  
  2877.     #
  2878.     # Now I have gotton the data that I need-- do the work
  2879.     #
  2880.     if (type=='schoenfeld') {
  2881.     if (ny==2)  y <- cbind(-1,y)
  2882.     temp <- .C("coxscho", n=as.integer(n),
  2883.                 as.integer(nvar),
  2884.                 as.double(y),
  2885.                 resid= x,
  2886.                 score * weights,
  2887.                 as.integer(newstrat),
  2888.                 as.integer(method=='efron'),
  2889.                 double(3*nvar))
  2890.  
  2891.     deaths <- y[,3]==1
  2892.  
  2893.     if (nvar==1) rr <- temp$resid[deaths]
  2894.     else rr <- matrix(temp$resid[deaths,], ncol=nvar) #pick rows, and kill attr
  2895.     if (length(strats)!=0) attr(rr, "strata")  <- table((strat[ord])[deaths])
  2896.     time <- c(y[deaths,2])  # 'c' kills all of the attributes
  2897.     if (is.matrix(rr)) dimnames(rr)<- list(time, names(object$coef))
  2898.     else               names(rr) <- time
  2899.  
  2900.     if (otype=='scaledsch') {
  2901.         ndead <- sum(deaths)
  2902.         coef <- ifelse(is.na(object$coef), 0, object$coef)
  2903.         if (nvar==1) rr <- rr*vv *ndead + coef
  2904.         else         rr <- rr %*%vv * ndead +
  2905.                         outer(rep(1,nrow(rr)),coef)
  2906.         }
  2907.     return(rr)
  2908.     }
  2909.  
  2910.     if (type=='score') {
  2911.     if (ny==2) {
  2912.         resid <- .C("coxscore", as.integer(n),
  2913.                 as.integer(nvar),
  2914.                 as.double(y),
  2915.                 x=x,
  2916.                 as.integer(newstrat),
  2917.                 score,
  2918.                 weights,
  2919.                 as.integer(method=='efron'),
  2920.                 resid= double(n*nvar),
  2921.                 double(2*nvar))$resid
  2922.         }
  2923.     else {
  2924.         resid<- .C("agscore",
  2925.                 as.integer(n),
  2926.                 as.integer(nvar),
  2927.                 as.double(y),
  2928.                 x,
  2929.                 as.integer(newstrat),
  2930.                 score,
  2931.                 weights,
  2932.                 as.integer(method=='efron'),
  2933.                 resid=double(n*nvar),
  2934.                 double(nvar*6))$resid
  2935.         }
  2936.     if (nvar >1) {
  2937.         rr <- matrix(0, n, nvar)
  2938.         rr[ord,] <- matrix(resid, ncol=nvar)
  2939.         dimnames(rr) <- list(names(object$resid), names(object$coef))
  2940.         }
  2941.     else rr[ord] <- resid
  2942.  
  2943.     if      (otype=='dfbeta') {
  2944.         if (is.matrix(rr)) rr <- rr %*% vv
  2945.         else               rr <- rr * vv
  2946.         }
  2947.     else if (otype=='dfbetas') {
  2948.         if (is.matrix(rr))  rr <- (rr %*% vv) %*% diag(sqrt(1/diag(vv)))
  2949.         else                rr <- rr * sqrt(vv)
  2950.         }
  2951.     }
  2952.  
  2953.     #
  2954.     # Multiply up by case weights, if requested
  2955.     #
  2956.     if (!is.null(weights) & weighted) {
  2957.     weights[ord] <- weights
  2958.     rr <- rr * weights
  2959.     }
  2960.  
  2961.     #Expand out the missing values in the result
  2962.     if (!is.null(object$na.action)) {
  2963.     rr <- naresid(object$na.action, rr)
  2964.     if (is.matrix(rr)) n <- nrow(rr)
  2965.     else               n <- length(rr)
  2966.     if (type=='deviance') status <- naresid(object$na.action, status)
  2967.     }
  2968.  
  2969.     # Collapse if desired
  2970.     if (!missing(collapse)) {
  2971.     if (length(collapse) !=n) stop("Wrong length for 'collapse'")
  2972.     rr <- rowsum(rr, collapse)
  2973.     }
  2974.  
  2975.     # Deviance residuals are computed after collapsing occurs
  2976.     if (type=='deviance')
  2977.     sign(rr) *sqrt(-2* (rr+
  2978.                   ifelse(status==0, 0, status*log(status-rr))))
  2979.     else rr
  2980.     }
  2981. residuals.survreg <-
  2982. function(object, type = c("deviance", "pearson", "working", "matrix"))
  2983. {
  2984.     type <- match.arg(type)
  2985.     rr <- switch(type,
  2986.         working = object$residuals,
  2987.         pearson = sqrt(object$weights) * object$residuals,
  2988.         deviance = object$dresiduals,
  2989.         matrix= {
  2990.         eta <- object$linear.predictors
  2991.         n   <- length(eta)
  2992.         y   <- object$y
  2993.         if (is.null(y))
  2994.             stop("Program deficiency-- must have y=T for matrix residuals")
  2995.         dist<- match(object$dist, c("extreme", "logistic",
  2996.                         "gaussian", "cauchy"))
  2997.         temp <-.C("survreg_g", as.integer(n),
  2998.                 as.double(y),
  2999.                 as.integer(ncol(y)),
  3000.                 eta,
  3001.                 as.double(object$parms),
  3002.                 deriv=matrix(double(n*6), ncol=6),
  3003.                 as.integer(6),
  3004.                 as.integer(dist))$deriv
  3005.         dimnames(temp) <- list(names(object$residuals),
  3006.                        c("loglik", "eta'", "eta''", "sig'",
  3007.                      "sig''", "eta'sig'"))
  3008.         temp
  3009.         }
  3010.         )
  3011.  
  3012.     #Expand out the missing values in the result
  3013.     if (!is.null(object$na.action))
  3014.      naresid(object$na.action, rr)
  3015.     else rr
  3016.     }
  3017. #SCCS 05/23/94 @(#)rowsum.s    4.4
  3018. rowsum <- function(x, group, reorder=T) {
  3019.     if (!is.numeric(x)) stop("x must be numeric")
  3020.     if (is.matrix(x)) dd <- dim(x)
  3021.     else              dd <- c(length(x), 1)
  3022.     n <- dd[1]
  3023.  
  3024.     if (length(group) !=n)  stop("Incorrect length for 'group'")
  3025.     if (any(is.na(group)))  stop("Missing values for 'group'")
  3026.     na.indicator <- max(1,x[!is.na(x)]) * n   #larger than any possible sum
  3027.     x[is.na(x)] <- na.indicator
  3028.  
  3029.     if (!is.numeric(group)) group <- as.factor(group)
  3030.     storage.mode(x) <- 'double'
  3031.     temp <- .C("rowsum", dd= as.integer(dd),
  3032.              as.double(na.indicator),
  3033.              x = x,
  3034.              as.double(group))
  3035.     new.n <- temp$dd[1]
  3036.     ugroup <- unique(group)
  3037.     if (is.matrix(x)){
  3038.     new.x <- temp$x[1:new.n,]
  3039.     dimnames(new.x) <- list(ugroup, dimnames(x)[[2]])
  3040.     if (reorder) new.x <- new.x[order(ugroup), ]
  3041.     }
  3042.     else {
  3043.     new.x <- temp$x[1:new.n]
  3044.     names(new.x) <- ugroup
  3045.     if (reorder) new.x <- new.x[order(ugroup)]
  3046.     }
  3047.  
  3048.     ifelse(new.x ==na.indicator, NA, new.x)
  3049.     }
  3050. # @(#)strata.s    4.9 07/21/93
  3051. # Create a strata variable, possibly from many objects
  3052. #
  3053. strata <- function(..., na.group=F, shortlabel=F) {
  3054.     words <- as.character((match.call())[-1])
  3055.     if (!missing(na.group)) words <- words[-1]
  3056.     allf <- list(...)
  3057.     if(length(allf) == 1 && is.list(ttt <- unclass(allf[[1]]))) {
  3058.         allf <- ttt
  3059.         words <- names(ttt)
  3060.         }
  3061.     nterms <- length(allf)
  3062.     what <- allf[[1]]
  3063. ### <TSL>
  3064.     if(!is.factor(what))
  3065.         what <- factor(what)
  3066. ###    levs <- unclass(what) - 1
  3067.     levs<-as.numeric(what) -1
  3068. ### </TSL>
  3069.     wlab <- levels(what)
  3070.     if (na.group && any(is.na(what))){
  3071.     levs[is.na(levs)] <- length(wlab)
  3072.     wlab <- c(wlab, "NA")
  3073.     }
  3074.     if (shortlabel) labs <- wlab
  3075.     else            labs <- paste(words[1], wlab, sep='=')
  3076.     for (i in (1:nterms)[-1]) {
  3077.     what <- allf[[i]]
  3078. ###<TSL>
  3079.     if(!is.factor(what))
  3080.         what <- factor(what)
  3081.     wlab <- levels(what)
  3082. ###     wlev <- unclass(what) - 1
  3083.     wlev<-as.numeric(what) -1
  3084. ### </TSL>
  3085.     if (na.group && any(is.na(wlev))){
  3086.         wlev[is.na(wlev)] <- length(wlab)
  3087.         wlab <- c(wlab, "NA")
  3088.         }
  3089.     if (!shortlabel) wlab <- format(paste(words[i], wlab, sep='='))
  3090.     levs <- wlev + levs*(length(wlab))
  3091.     labs <- paste(rep(labs, rep(length(wlab), length(labs))),
  3092.               rep(wlab, length(labs)), sep=', ')
  3093.     }
  3094.     levs <- levs + 1
  3095.     ulevs <- sort(unique(levs[!is.na(levs)]))
  3096.     levs <- match(levs, ulevs)
  3097.     labs <- labs[ulevs]
  3098. ### <TSL>    class(levs) <- "factor"
  3099.     levs<-as.factor(levs)
  3100. ###</TSL>
  3101.     levels(levs) <- labs
  3102.     levs
  3103.     }
  3104. #SCCS 09/27/96 @(#)summary.coxph.s    4.6
  3105. summary.coxph <-
  3106.  function(cox, table = T, coef = T, conf.int = 0.95, scale = 1,
  3107.             digits = max(options()$digits - 4, 3))
  3108.     {
  3109.     if (!is.null(cl<- cox$call)) {
  3110.     cat("Call:\n")
  3111.     dput(cl)
  3112.     cat("\n")
  3113.     }
  3114.     if (!is.null(cox$fail)) {
  3115.     cat(" Coxreg failed.", cox$fail, "\n")
  3116.     return()
  3117.     }
  3118.     savedig <- options(digits = digits)
  3119.     on.exit(options(savedig))
  3120.  
  3121.     omit <- cox$na.action
  3122.     if (length(omit))
  3123.     cat("  n=", cox$n, " (", naprint(omit), ")\n", sep="")
  3124.     else cat("  n=", cox$n, "\n")
  3125.     if (length(cox$icc))
  3126.     cat("  robust variance based on", cox$icc[1],
  3127.         "groups, intra-class correlation =", format(cox$icc[2:3]), "\n")
  3128.     if (is.null(cox$coef)) {   # Null model
  3129.     cat ("   Null model\n")
  3130.     return()
  3131.     }
  3132.  
  3133.     beta <- cox$coef
  3134.     nabeta <- !(is.na(beta))          #non-missing coefs
  3135.     beta2 <- beta[nabeta]
  3136.     if(is.null(beta) | is.null(cox$var))
  3137.         stop("Input is not valid")
  3138.  
  3139.     if (is.null(cox$naive.var)) {
  3140.     se <- sqrt(diag(cox$var))
  3141.     wald.test <-  sum(beta2 * solve(cox$var[nabeta,nabeta], beta2))
  3142.     }
  3143.     else {
  3144.     nse <- sqrt(diag(cox$naive.var))        #naive se
  3145.     se <- sqrt(diag(cox$var))
  3146.     wald.test <-  sum(beta2 * solve(cox$var[nabeta,nabeta], beta2))
  3147.     }
  3148.     if(coef) {
  3149.     if (is.null(cox$naive.var)) {
  3150.         tmp <- cbind(beta, exp(beta), se, beta/se,
  3151.            signif(1 - pchisq((beta/ se)^2, 1), digits -1))
  3152.         dimnames(tmp) <- list(names(beta), c("coef", "exp(coef)",
  3153.         "se(coef)", "z", "p"))
  3154.         }
  3155.     else {
  3156.         tmp <- cbind(beta, exp(beta), nse, se, beta/se,
  3157.            signif(1 - pchisq((beta/ se)^2, 1), digits -1))
  3158.         dimnames(tmp) <- list(names(beta), c("coef", "exp(coef)",
  3159.         "se(coef)", "robust se", "z", "p"))
  3160.         }
  3161.         cat("\n")
  3162.         prmatrix(tmp)
  3163.         }
  3164.     if(conf.int) {
  3165.         z <- qnorm((1 + conf.int)/2, 0, 1)
  3166.         beta <- beta * scale
  3167.         se <- se * scale
  3168.         tmp <- cbind(exp(beta), exp(-beta), exp(beta - z * se),
  3169.             exp(beta + z * se))
  3170.         dimnames(tmp) <- list(names(beta), c("exp(coef)", "exp(-coef)",
  3171.             paste("lower .", round(100 * conf.int, 2), sep = ""),
  3172.             paste("upper .", round(100 * conf.int, 2), sep = "")))
  3173.         cat("\n")
  3174.         prmatrix(tmp)
  3175.         }
  3176.     logtest <- -2 * (cox$loglik[1] - cox$loglik[2])
  3177.     sctest <- cox$score
  3178.     df <- length(beta2)
  3179.     cat("\n")
  3180.     cat("Rsquare=", format(round(1-exp(-logtest/cox$n),3)),
  3181.     "  (max possible=", format(round(1-exp(2*cox$loglik[1]/cox$n),3)),
  3182.     ")\n" )
  3183.     cat("Likelihood ratio test= ", format(round(logtest, 2)), "  on ",
  3184.     df, " df,", "   p=", format(1 - pchisq(logtest, df)),
  3185.     "\n", sep = "")
  3186.     cat("Wald test            = ", format(round(wald.test, 2)), "  on ",
  3187.     df, " df,", "   p=", format(1 - pchisq(wald.test, df)),
  3188.     "\n", sep = "")
  3189.     cat("Efficient score test = ", format(round(sctest, 2)), "  on ", df,
  3190.         " df,", "   p=", format(1 - pchisq(sctest, df)), "\n\n", sep = 
  3191.         "")
  3192.     if (!is.null(cox$naive.var))
  3193.       cat("   (Note: the likelihood ratio and efficient score tests",
  3194.       " assume independence of the observations).\n")
  3195.     invisible()
  3196.     }
  3197. #SCCS 02/28/95 @(#)summary.survfit.s    1.7
  3198. summary.survfit <- function(fit, times, censored=F, scale=1, ...) {
  3199.     if (!inherits(fit, 'survfit'))
  3200.         stop("Invalid data")
  3201.  
  3202.     n <- length(fit$time)
  3203.     stime <- fit$time/scale
  3204.     if (is.null(fit$strata)) {
  3205.     stemp <- rep(1,n)
  3206.     nstrat <- 1
  3207.     }
  3208.     else {
  3209.     nstrat <- length(fit$strata)
  3210.     stemp <- rep(1:nstrat,fit$strata)
  3211.     }
  3212.  
  3213.     surv <- as.matrix(fit$surv)
  3214.     if (is.null(fit$std.err)) std.err <- NULL
  3215.     else                      std.err <- fit$std.err * surv
  3216.  
  3217.     if (!is.null(fit$lower)) {
  3218.     lower <- as.matrix(fit$lower)
  3219.     upper <- as.matrix(fit$upper)
  3220.     }
  3221.  
  3222.     if (missing(times)) {
  3223.     if (censored) {
  3224.         times <- stime
  3225.         n.risk<- fit$n.risk
  3226.         n.event <- fit$n.event
  3227.         }
  3228.     else {
  3229.         who    <- (fit$n.event >0)
  3230.         times  <-  stime[who]
  3231.         n.risk <-  fit$n.risk[who]
  3232.         n.event <- fit$n.event[who]
  3233.         stemp <- stemp[who]
  3234.         surv <- surv[who,,drop=F]
  3235.         if (!is.null(std.err)) std.err <- std.err[who,,drop=F]
  3236.         if (!is.null(fit$lower)) {
  3237.         lower <- lower[who,,drop=F]
  3238.         upper <- upper[who,,drop=F]
  3239.         }
  3240.         }
  3241.     }
  3242.  
  3243.     else {  #this case is much harder
  3244.     if (any(times<0)) stop("Invalid time point requested")
  3245.         if(max(fit$time) < min(times))
  3246.             stop("Requested times are all beyond the end of the survival curve")
  3247.     if (length(times) >1 )
  3248.         if (any(diff(times)<0)) stop("Times must be in increasing order")
  3249.  
  3250.     temp <- .C("survindex2", as.integer(n),
  3251.                   as.double(stime),
  3252.                   as.integer(stemp),
  3253.                   as.integer(length(times)),
  3254.                   as.double(times),
  3255.                   as.integer(nstrat),
  3256.                   indx = integer(nstrat*length(times)),
  3257.                   indx2= integer(nstrat*length(times)) )
  3258.     keep <- temp$indx >=0
  3259.     indx <- temp$indx[keep]
  3260.     ones <- (temp$indx2==1)[keep]
  3261.     ties <- (temp$indx2==2)[keep]  #data set time === requested time
  3262.  
  3263.     times <- rep(times, nstrat)[keep]
  3264.     n.risk <- fit$n.risk[indx+1 - (ties+ones)]
  3265.     surv   <- surv[indx,,drop=F];   surv[ones,] <- 1
  3266.     if (!is.null(std.err)) {
  3267.         std.err<- std.err[indx,,drop=F]
  3268.         std.err[ones,] <-0
  3269.         }
  3270.     fit$n.event[stime>max(times)] <- 0
  3271.     n.event <- (cumsum(c(0,fit$n.event)))[ifelse(ones, indx, indx+1)]
  3272.     n.event<-  diff(c(0, n.event))
  3273.  
  3274.     if (!is.null(fit$lower)) {
  3275.         lower <- lower[indx,,drop=F];  lower[ones,] <- 1;
  3276.         upper <- upper[indx,,drop=F];  upper[ones,] <- 1;
  3277.         }
  3278.  
  3279.     stemp <- stemp[indx]
  3280.     }
  3281.  
  3282.     ncurve <- ncol(surv)
  3283.     temp <- list(surv=surv, time=times, n.risk=n.risk, n.event=n.event,
  3284.             conf.int=fit$conf.int)
  3285.     if (ncurve==1) {
  3286.     temp$surv <- drop(temp$surv)
  3287.     if (!is.null(std.err)) temp$std.err <- drop(std.err)
  3288.     if (!is.null(fit$lower)) {
  3289.         temp$lower <- drop(lower)
  3290.         temp$upper <- drop(upper)
  3291.         }
  3292.     }
  3293.     else {
  3294.     if (!is.null(std.err)) temp$std.err <- std.err
  3295.     if (!is.null(fit$lower)) {
  3296.         temp$lower <- lower
  3297.         temp$upper <- upper
  3298.         }
  3299.     }
  3300.     if (!is.null(fit$strata))
  3301.     temp$strata <- factor(stemp,
  3302.         labels = names(fit$strata)[sort(unique(stemp))])
  3303.     temp$call <- fit$call
  3304.     if (!is.null(fit$na.action)) temp$na.action <- fit$na.action
  3305.     class(temp) <- 'summary.survfit'
  3306.     temp
  3307.     }
  3308. # SCCS @(#)summary.survreg.s    4.9  12/30/92
  3309. summary.survreg<- function(object, correlation = T)
  3310. {
  3311.     if (!is.null(object$fail)) {
  3312.     warning(" Survreg failed.", x$fail, "   No summary provided\n")
  3313.     return(invisible(object))
  3314.     }
  3315.     wt <- object$weights
  3316.     fparms <- object$fixed
  3317.     coef <- c(object$coef, object$parms[!fparms])
  3318.     resid <- object$residuals
  3319.     dresid <- object$dresiduals
  3320.     n <- length(resid)
  3321.     p <- sum(!is.na(coef))
  3322.     if(p==0) {
  3323.         warning("This model has zero rank --- no summary is provided")
  3324.         return(object)
  3325.         }
  3326.     nsingular <- length(coef) - p
  3327.     rdf <- object$df.resid
  3328.     if(is.null(rdf))
  3329.         rdf <- n - p
  3330. # This doesn't seem to do anything
  3331. #    R <- object$R   #check for rank deficiencies
  3332. #    if(p < max(dim(R)))
  3333. #        R <- R[1:p,     #coded by pivoting
  3334. #        1:p]
  3335.     if(!is.null(wt)) {
  3336.         wt <- wt^0.5
  3337.         resid <- resid * wt
  3338.         excl <- wt == 0
  3339.         if(any(excl)) {
  3340.             warning(paste(sum(excl), 
  3341.                 "rows with zero weights not counted"))
  3342.             resid <- resid[!excl]
  3343.             if(is.null(object$df.residual))
  3344.                 rdf <- rdf - sum(excl)
  3345.             }
  3346.         }
  3347.     famname <- unlist(object$family["name"])
  3348.     if(is.null(famname))
  3349.     famname <- "gaussian"
  3350.     nas <- is.na(coef)
  3351.     cnames <- names(coef[!nas])
  3352.     coef <- matrix(rep(coef[!nas], 4), ncol = 4)
  3353.     dimnames(coef) <- list(cnames, c("Value", "Std. Error", "z value", "p"))
  3354.     stds <- sqrt(diag(object$var[!nas,!nas,drop=F]))
  3355.     coef[, 2] <- stds
  3356.     coef[, 3] <- coef[, 1]/stds
  3357.     coef[, 4] <- 2*pnorm(-abs(coef[,3]))
  3358.     if(correlation && sum(!nas)>1 ) {
  3359.     correl <- diag(1/stds) %*% object$var[!nas, !nas] %*% diag(1/stds)
  3360.         dimnames(correl) <- list(cnames, cnames)
  3361.         }
  3362.     else correl <- NULL
  3363.     ocall <- object$call
  3364.     if(!is.null(form <- object$formula)) {
  3365.         if(is.null(ocall$formula))
  3366.         ocall <- match.call(get("survreg"), ocall)
  3367.         ocall$formula <- form
  3368.         }
  3369.     sd <- survreg.distributions[[famname]]
  3370.     pprint<- paste(sd$name, 'distribution:', sd$print(object$parms, fparms))
  3371.     structure(list(call = ocall, terms = object$terms, coefficients = coef,
  3372.     scale= NULL, df = c(p, rdf), deviance.resid = dresid,
  3373.     var=object$var, correlation = correl, deviance = deviance(object),
  3374.     null.deviance = object$null.deviance, iter = object$iter,
  3375.     nas = nas, parms=pprint, loglik=object$loglik[2]),
  3376.     class = "summary.survreg")
  3377.     }
  3378. #SCCS @(#)survdiff.fit.s    1.1 01/07/96
  3379. survdiff.fit <- function(y, x, strat, rho=0) {
  3380.     #
  3381.     # This routine is almost always called from survdiff
  3382.     #  If called directly, remember that it does no error checking
  3383.     #
  3384.     n <- length(x)
  3385.     if (ncol(y) !=2) stop ("Invalid y matrix")
  3386.     if (nrow(y) !=n | length(x) !=n) stop("Data length mismatch")
  3387.  
  3388.     ngroup <- length(unique(x))
  3389.     if (ngroup <2) stop ("There is only 1 group")
  3390.     if (is.category(x)) x <- as.numeric(x)
  3391.     else x <- match(x, unique(x))
  3392.  
  3393.     if (missing(strat)) strat <- rep(1,n)
  3394.     else strat <- as.numeric(as.factor(strat))
  3395.     nstrat <- length(unique(strat))
  3396.     if (length(strat) !=n) stop("Data length mismatch")
  3397.  
  3398.     ord <- order(strat, y[,1], -y[,2])
  3399.     strat2 <- c(1*(diff(strat[ord])!=0), 1)
  3400.  
  3401.     xx <- .C("survdiff2", as.integer(n),
  3402.            as.integer(ngroup),
  3403.            as.integer(nstrat),
  3404.            as.double(rho),
  3405.            as.double(y[ord,1]),
  3406.            as.integer(y[ord,2]),
  3407.            as.integer(x[ord]),
  3408.            as.integer(strat2),
  3409.            observed = double(ngroup*nstrat),
  3410.            expected = double(ngroup*nstrat),
  3411.            var.e    = double(ngroup * ngroup),
  3412.            double(ngroup), double(n))
  3413.  
  3414.     if (nstrat==1)  list(expected = xx$expected,
  3415.              observed = xx$observed,
  3416.              var      = matrix(xx$var, ngroup, ngroup))
  3417.     else            list(expected = matrix(xx$expected, ngroup),
  3418.              observed = matrix(xx$observed, ngroup),
  3419.              var      = matrix(xx$var, ngroup, ngroup))
  3420.     }
  3421. #SCCS 01/07/96 @(#)survdiff.s    4.10
  3422. survdiff <- function(formula, data, subset, na.action, rho=0) {
  3423.     call <- match.call()
  3424.     m <- match.call(expand=F)
  3425.     m$rho <- NULL
  3426. ###
  3427. ###    Terms <- if(missing(data)) terms(formula, 'strata')
  3428. ###         else              terms(formula, 'strata', data=data)
  3429.     Terms <-terms(formula, 'strata')
  3430. ### </TSL>
  3431.     m$formula <- Terms
  3432.     m[[1]] <- as.name("model.frame")
  3433.     m <- eval(m, sys.parent())
  3434.     y <- model.extract(m, response)
  3435.     if (!inherits(y, "Surv")) stop("Response must be a survival object")
  3436.     if (attr(y, 'type') != 'right') stop("Right censored data only")
  3437.     ny <- ncol(y)
  3438.     n <- nrow(y)
  3439.  
  3440.     offset<- attr(Terms, "offset")
  3441.     if (!is.null(offset)) {
  3442.     #one sample test
  3443.     offset <- as.numeric(m[[offset]])
  3444. ###<TSL>
  3445. ###    if (length(Terms)>0) stop("Cannot have both an offset and groups")
  3446.     if (length(attr(Terms,"term.labels"))>0) stop("Cannot have both an offset and groups")
  3447. ###</TSL>
  3448.     if (any(offset <0 | offset >1))
  3449.         stop("The offset must be a survival probability")
  3450.     expected <- sum(1-offset)
  3451.     observed <- sum(y[,ny])
  3452.     if (rho!=0) {
  3453.         num <- sum(1/rho - ((1/rho + y[,ny])*offset^rho))
  3454.         var <- sum(1- offset^(2*rho))/(2*rho)
  3455.         }
  3456.     else {
  3457.         var <-  sum(-log(offset))
  3458.         num <-  var - observed
  3459.         }
  3460.     chi <- num*num/var
  3461.     rval <-list(n= n, obs = observed, exp=expected, var=var,
  3462.             chisq= chi)
  3463.     }
  3464.  
  3465.     else { #k sample test
  3466.     strats <- attr(Terms, "specials")$strata
  3467.     if (length(strats)) {
  3468.         temp <- untangle.specials(Terms, 'strata', 1)
  3469.         dropx <- temp$terms
  3470.         if (length(temp$vars)==1) strata.keep <- m[[temp$vars]]
  3471.         else strata.keep <- strata(m[,temp$vars], shortlabel=T)
  3472.         }
  3473.     else strata.keep <- rep(1,nrow(m))
  3474.  
  3475.     #Now create the group variable
  3476.     if (length(strats)) ll <- attr(Terms[-dropx], 'term.labels')
  3477.     else                ll <- attr(Terms, 'term.labels')
  3478.     if (length(ll) == 0) stop("No groups to test")
  3479.     else groups <- strata(m[ll])
  3480.  
  3481.     fit <- survdiff.fit(y, groups, strata.keep, rho)
  3482.     if (is.matrix(fit$observed)){
  3483.         otmp <- apply(fit$observed,1,sum)
  3484.         etmp <- apply(fit$expected,1,sum)
  3485.         }
  3486.     else {
  3487.         otmp <- fit$observed
  3488.         etmp <- fit$expected
  3489.         }
  3490.     df   <- (etmp >0)                #remove groups with exp=0
  3491.     if (sum(df) <2) chi <- 0         # No test, actually
  3492.     else {
  3493.         temp2 <- ((otmp - etmp)[df])[-1]
  3494.         vv <- (fit$var[df,df])[-1,-1, drop=F]
  3495.         chi <- sum(solve(vv, temp2) * temp2)
  3496.         }
  3497.  
  3498.     rval <-list(n= table(groups), obs = fit$observed,
  3499.             exp = fit$expected, var=fit$var,  chisq=chi)
  3500.     if (length(strats)) rval$strata <- table(strata.keep)
  3501.     }
  3502.  
  3503.     na.action <- attr(m, "na.action")
  3504.     if (length(na.action)) rval$na.action <- na.action
  3505.     rval$call <- call
  3506.     attr(rval, "class") <- 'survdiff'
  3507.     rval
  3508.     }
  3509. # SCCS @(#)survexp.cfit.s    4.5 03/14/95
  3510. #
  3511. #  Do expected survival based on a Cox model
  3512. #   A fair bit of the setup work is identical to survfit.coxph, i.e.,
  3513. #     to reconstruct the data frame
  3514. #
  3515. #  The execution path for individual survival is completely separate, and
  3516. #    a whole lot simpler.
  3517. #
  3518. survexp.cfit <- function(x, y, death, individual, cox, se.fit, method) {
  3519.     if (!is.matrix(x)) stop("x must be a matrix")
  3520.  
  3521.     #
  3522.     # If it is individual survival, things are fairly easy
  3523.     #    (the parent routine has guarranteed NO strata in the Cox model
  3524.     #
  3525.     if (individual) {
  3526.     fit <- survfit.coxph(cox, se.fit=F)
  3527.     risk <- x[,-1,drop=F] %*% cox$coef  -  sum(cox$coef *cox$means)
  3528.     nt <- length(fit$time)
  3529.     surv <- approx(-c(0,fit$time), c(1,fit$surv), -y,
  3530.                 method='constant', rule=2, f=1)$y
  3531.     return(list(times=y, surv=c(surv^(exp(risk)))))
  3532.     }
  3533.  
  3534.     # Otherwise, get on with the real work
  3535.     temp <- coxph.getdata(cox, y=T, x=se.fit, strata=F)
  3536.     cy <- temp$y
  3537.     cx <- temp$x
  3538.     cn <- nrow(cy)
  3539.     nvar <- length(cox$coef)
  3540.  
  3541.     if (ncol(x) != (1+ nvar))
  3542.     stop("x matrix does not match the cox fit")
  3543.  
  3544.     ngrp <- max(x[,1])
  3545.     if (!is.logical(death)) stop("Invalid value for death indicator")
  3546.  
  3547.     if (missing(method))
  3548.     method <- (1 + 1*(cox$method=='breslow') +2*(cox$method=='efron')
  3549.              + 10*(death))
  3550.     else stop("Program unfinished")
  3551.  
  3552.     #
  3553.     # Data appears ok so proceed
  3554.     #  First sort the old data set
  3555.     # Also, expand y to (start, stop] form.  This leads to slower processing,
  3556.     #  but I only have to program one case instead of 2.
  3557.     if (ncol(cy) ==2) cy <- cbind(-1, cy)
  3558.     ord <- order(cy[,2], -cy[,3])
  3559.     cy  <- cy[ord,]
  3560.     score <- exp(cox$linear.predictors[ord])
  3561.     if (se.fit) cx <- cx[ord,]
  3562.     else  cx <- 0   #dummy, for .C call
  3563.  
  3564.  
  3565.     #
  3566.     # Process the new data
  3567.     #
  3568.     if (missing(y) || is.null(y)) y <- rep(max(cy[,2]), nrow(x))
  3569.     ord <- order(x[,1])
  3570.     x[,1] <- x[,1] - min(x[,1])
  3571.     n <- nrow(x)
  3572.     ncurve <- length(unique(x[,1]))
  3573.     npt <- length(unique(cy[cy[,3]==1,2]))  #unique death times
  3574.     xxx  <- .C('agsurv3', as.integer(n),
  3575.               as.integer(nvar),
  3576.               as.integer(ncurve),
  3577.               as.integer(npt),
  3578.               as.integer(se.fit),
  3579.               as.double(score),
  3580.               y = as.double(y[ord]),
  3581.               x[ord,],
  3582.               cox$coef,
  3583.               cox$var,
  3584.               cox$means,
  3585.               as.integer(cn),
  3586.               cy = cy,
  3587.               cx,
  3588.               surv = matrix(0, npt, ncurve),
  3589.               varhaz = matrix(0, npt, ncurve),
  3590.               nrisk  = matrix(0, npt, ncurve),
  3591.               as.integer(method))
  3592.  
  3593.     surv <- apply(xxx$surv, 2, cumprod)
  3594.     if (se.fit)
  3595.     list(surv=surv, n=xxx$nrisk, times=xxx$cy[1:npt],
  3596.             se=sqrt(xxx$varhaz)/surv)
  3597.     else
  3598.     list(surv=surv, n=xxx$nrisk, times=xxx$cy[1:npt,1] )
  3599.     }
  3600. # SCCS @(#)survexp.fit.s    4.6  05/23/94
  3601. #  Actually compute the expected survival for one or more cohorts
  3602. #    of subjects.  If each subject is his/her own group, it gives individual
  3603. #    survival
  3604. survexp.fit <- function(x, y, times, death, ratetable) {
  3605.     if (!is.matrix(x)) stop("x must be a matrix")
  3606.     if (ncol(x) != (1+length(dim(ratetable))))
  3607.     stop("x matrix does not match the rate table")
  3608.     atts <- attributes(ratetable)
  3609.     rfac <- atts$factor
  3610.     if (length(rfac) != ncol(x)-1) stop("Wrong length for rfac")
  3611.     ngrp <- max(x[,1])
  3612.     times <- sort(unique(times))
  3613.     if (any(times <0)) stop("Negative time point requested")
  3614.     if (missing(y))  y <- rep(max(times), nrow(x))
  3615.     ntime <- length(times)
  3616.     if (!is.logical(death)) stop("Invalid value for death indicator")
  3617.  
  3618.     cuts <- atts$cutpoints
  3619.     us.special <- (rfac >1)
  3620.     if (any(us.special)) {  #special handling for US pop tables
  3621.     if (sum(us.special) >1)
  3622.         stop("Two columns marked for special handling as a US rate table")
  3623.     #slide entry date so that it appears that they were born on Jan 1
  3624.     cols <- 1+match(c("age", "year"), attr(ratetable, "dimid"))
  3625.     if (any(is.na(cols))) stop("Ratetable does not have expected shape")
  3626.     temp <- date.mdy(x[,cols[2]]-x[,cols[1]])
  3627.     x[,cols[2]] <- x[,cols[2]] - mdy.date(temp$month, temp$day, 1960)
  3628.     # Doctor up "cutpoints"
  3629.     temp <- (1:length(rfac))[us.special]
  3630.     nyear <- length(cuts[[temp]])
  3631.     nint <- rfac[temp]       #intervals to interpolate over
  3632.     cuts[[temp]] <- round(approx(nint*(1:nyear), cuts[[temp]],
  3633.                     nint:(nint*nyear))$y - .0001)
  3634.     }
  3635.     temp <- .C('pyears3',
  3636.             as.integer(death),
  3637.             as.integer(nrow(x)),
  3638.             as.integer(length(atts$dim)),
  3639.             as.integer(rfac),
  3640.             as.integer(atts$dim),
  3641.             as.double(unlist(cuts)),
  3642.             ratetable,
  3643.             as.double(x),
  3644.             as.double(y),
  3645.             as.integer(ntime),
  3646.             as.integer(ngrp),
  3647.             as.double(times),
  3648.             surv = double(ntime * ngrp),
  3649.             n   = integer(ntime *ngrp))
  3650.     if (ntime==1) list(surv=temp$surv, n=temp$n)
  3651.     else if (ngrp >1)
  3652.      list(surv=apply(matrix(temp$surv, ntime, ngrp),2,cumprod),
  3653.          n=   matrix(temp$n, ntime, ngrp))
  3654.     else list(surv=cumprod(temp$surv), n=temp$n)
  3655.     }
  3656. #SCCS  @(#)survexp.s    4.21 03/14/95
  3657. survexp <- function(formula=formula(data), data=sys.parent(),
  3658.     weights, subset, na.action,
  3659.     times,  cohort=T,  conditional=F,
  3660.     ratetable=survexp.us, scale=1, npoints, se.fit,
  3661.     model=F, x=F, y=F) {
  3662.  
  3663.     call <- match.call()
  3664.     m <- match.call(expand=F)
  3665.     m$ratetable <- m$model <- m$x <- m$y <- m$scale<- m$cohort <- NULL
  3666.     m$times <- m$conditional <- m$npoints <- m$se.fit <- NULL
  3667. ###<TSL>
  3668. ###    Terms <- if(missing(data)) terms(formula, 'ratetable')
  3669. ###         else              terms(formula, 'ratetable',data=data)
  3670.      Terms <- terms(formula, 'ratetable')
  3671. ###</TSL>
  3672.     if (any(attr(Terms, 'order') >1))
  3673.         stop("Survexp cannot have interaction terms")
  3674.     m$formula <- Terms
  3675.     m[[1]] <- as.name("model.frame")
  3676.     m <- eval(m, sys.parent())
  3677.     n <- nrow(m)
  3678.  
  3679.     if (!missing(times)) {
  3680.     if (any(times<0)) stop("Invalid time point requested")
  3681.     if (length(times) >1 )
  3682.         if (any(diff(times)<0)) stop("Times must be in increasing order")
  3683.     }
  3684.  
  3685.     Y <- model.extract(m, 'response')
  3686.     no.Y <- is.null(Y)
  3687.     if (!no.Y) {
  3688.     if (is.matrix(Y)) {
  3689.         if (is.Surv(Y) && attr(Y, 'type')=='right') Y <- Y[,1]
  3690.         else stop("Illegal response value")
  3691.         }
  3692.     if (any(Y<0)) stop ("Negative follow up time")
  3693.     if (missing(npoints)) temp <- unique(Y)
  3694.     else                  temp <- seq(min(Y), max(Y), length=npoints)
  3695.     if (missing(times)) newtime <- sort(temp)
  3696.     else  newtime <- sort(unique(c(times, temp[temp<max(times)])))
  3697.     }
  3698.     else conditional <- F
  3699.     weights <- model.extract(m, 'weights')
  3700.     if (!is.null(weights)) warning("Weights ignored")
  3701.      rate <- attr(Terms, "specials")$ratetable
  3702.     if (length(rate)==0)
  3703.     stop("Must have a ratetable() call in the formula")
  3704.     if (length(rate) >1 )
  3705.     stop ("Can have only 1 ratetable() call in a formula")
  3706.  
  3707.     if (no.Y) ovars <- attr(Terms, 'term.labels')[-rate]
  3708.     else      ovars <- attr(Terms, 'term.labels')[-(rate-1)]
  3709.  
  3710.     if (is.ratetable(ratetable)) {
  3711.     israte <- T
  3712.     if (no.Y) {
  3713.         if (missing(times))
  3714.            stop("There is no times argument, and no follow-up times are given in the formula")
  3715.         else newtime <- sort(unique(times))
  3716.         Y <- rep(max(times), n)
  3717.         }
  3718.     se.fit <- F
  3719.     rtemp <- match.ratetable(m[,rate], ratetable)
  3720.     R <- rtemp$R
  3721.     if (!is.null(rtemp$call)) {  #need to dop some dimensions from ratetable
  3722.         ratetable <- eval(parse(text=rtemp$call))
  3723.         }
  3724.        }
  3725.     else if (inherits(ratetable, 'coxph')) {
  3726.     israte <- F
  3727.     Terms <- ratetable$terms
  3728.     if (!inherits(Terms, 'terms'))
  3729.         stop("invalid terms component of fit")
  3730.     if (!is.null(attr(Terms, 'offset')))
  3731.         stop("Cannot deal with models that contain an offset")
  3732.     m2 <- data.frame(unclass(m[,rate]))
  3733.     strats <- attr(Terms, "specials")$strata
  3734.     if (length(strats))
  3735.         stop("survexp cannot handle stratified Cox models")
  3736.     R <- model.matrix(delete.response(Terms), m2)[,-1,drop=F]
  3737.     if (any(dimnames(R)[[2]] != names(ratetable$coef)))
  3738.         stop("Unable to match new data to old formula")
  3739.     if (no.Y) {
  3740.         if (missing(se.fit)) se.fit <- T
  3741.         }
  3742.     else se.fit <- F
  3743.     }
  3744.     else stop("Invalid ratetable argument")
  3745.  
  3746.     if (cohort) {
  3747.     # Now process the other (non-ratetable) variables
  3748.     if (length(ovars)==0)  X <- rep(1,n)  #no categories
  3749.     else {
  3750.         odim <- length(ovars)
  3751.         for (i in 1:odim) {
  3752.         temp <- m[[ovars[i]]]
  3753.         ctemp <- class(temp)
  3754.         if (!is.null(ctemp) && ctemp=='tcut')
  3755.             stop("Can't use tcut variables in expected survival")
  3756.         }
  3757.         X <- strata(m[ovars])
  3758.         }
  3759.  
  3760.     #do the work
  3761.     if (israte)
  3762.         temp <- survexp.fit(cbind(as.numeric(X),R), Y, newtime,
  3763.                    conditional, ratetable)
  3764.     else {
  3765.         temp <- survexp.cfit(cbind(as.numeric(X),R), Y, conditional, F,
  3766.                    ratetable, se.fit=se.fit)
  3767.         newtime <- temp$times
  3768.         }
  3769.     #package the results
  3770.     if (missing(times)) {
  3771.         n.risk <- temp$n
  3772.         surv <- temp$surv
  3773.         if (se.fit) err <- temp$se
  3774.         }
  3775.     else {
  3776.         if (israte) keep <- match(times, newtime)
  3777.         else {
  3778.         # taken straight out of summary.survfit....
  3779.         n <- length(temp$times)
  3780.         temp2 <- .C("survindex2", as.integer(n),
  3781.                       as.double(temp$times),
  3782.                       as.integer(rep(1,n)),
  3783.                       as.integer(length(times)),
  3784.                       as.double(times),
  3785.                       as.integer(1),
  3786.                       indx = integer(length(times)),
  3787.                       indx2= integer(length(times)) )
  3788.         keep <- temp2$indx[temp2$indx>0]
  3789.         }
  3790.  
  3791.         if (is.matrix(temp$surv)) {
  3792.         surv <- temp$surv[keep,,drop=F]
  3793.         n.risk <- temp$n[keep,,drop=F]
  3794.         if (se.fit) err <- temp$se[keep,,drop=F]
  3795.         }
  3796.         else {
  3797.         surv <- temp$surv[keep]
  3798.         n.risk <- temp$n[keep]
  3799.         if (se.fit) err <- temp$se[keep]
  3800.         }
  3801.         newtime <- times
  3802.         }
  3803.     newtime <- newtime/scale
  3804.     if (length(ovars)) {    #matrix output
  3805.         if (no.Y && israte){ # n's are all the same, so just send a vector
  3806.         dimnames(surv) <- list(NULL, levels(X))
  3807.         out <- list(call=call, surv=surv, n.risk=c(n.risk[,1]),
  3808.                 time=newtime)
  3809.         }
  3810.         else {
  3811.         #Need a matrix of n's, and a strata component
  3812.         out <- list(call=call, surv=surv, n.risk=n.risk,
  3813.                 time = newtime)
  3814.         tstrat <- rep(nrow(surv), ncol(surv))
  3815.         names(tstrat) <- levels(X)
  3816.         out$strata <- tstrat
  3817.         }
  3818.         if (se.fit) out$std.err <- err
  3819.         }
  3820.     else {
  3821.          out <- list(call=call, surv=c(surv), n.risk=c(n.risk),
  3822.                time=newtime)
  3823.          if (se.fit) out$std.err <- c(err)
  3824.          }
  3825.  
  3826.     na.action <- attr(m, "na.action")
  3827.     if (length(na.action))  out$na.action <- na.action
  3828.     if (model) out$model <- m
  3829.     else {
  3830.         if (x) out$x <- structure(cbind(X, R),
  3831.         dimnames=list(row.names(m), c("group", dimid)))
  3832.         if (y) out$y <- Y
  3833.         }
  3834.     if (israte && !is.null(rtemp$summ)) out$summ <- rtemp$summ
  3835.     if (no.Y) out$method <- 'exact'
  3836.     else if (conditional) out$method <- 'conditional'
  3837.     else                  out$method <- 'cohort'
  3838.     class(out) <- c("survexp", "survfit")
  3839.     out
  3840.     }
  3841.  
  3842.     else { #individual survival
  3843.     if (no.Y) stop("For non-cohort, an observation time must be given")
  3844.     if (israte)
  3845.         temp <- survexp.fit (cbind(1:n,R), Y, max(Y), T, ratetable)
  3846.     else temp<- survexp.cfit(cbind(1:n,R), Y, F, T, ratetable, F)
  3847.     xx <- temp$surv
  3848.     names(xx) <- row.names(m)
  3849.     na.action <- attr(m, "na.action")
  3850.     if (length(na.action)) naresid(na.action, xx)
  3851.     else xx
  3852.     }
  3853.     }
  3854. #SCCS  @(#)survfit.coxph.null.s    4.10 08/25/94
  3855. survfit.coxph.null <-
  3856.   function(object, newdata, se.fit=T, conf.int=.95, individual=F,
  3857.         type=c('tsiatis', 'kaplan-meier'),
  3858.         conf.type=c('log', 'log-log', 'plain', 'none'), ...) {
  3859.     # May have strata and/or offset terms, linear predictor = offset
  3860.     #  newdata doesn't make any sense
  3861.     #  This is survfit.coxph with lots of lines removed
  3862.  
  3863.     call <- match.call()
  3864.     Terms <- terms(object)
  3865.     strat <- attr(Terms, "specials")$strata
  3866.     n <- object$n
  3867.     score <- exp(object$linear.predictor)
  3868.     method <- match.arg(type)
  3869.     if (!se.fit) conf.type <- 'none'
  3870.     else conf.type <- match.arg(conf.type)
  3871.  
  3872.     y <- object$y
  3873.     stratx <- object$strata
  3874.     if (is.null(y) || (length(strat) && is.null(stratx))) {
  3875.     # I need the model frame
  3876.     m <- model.frame(object)
  3877.     if (is.null(stratx)) {
  3878.         temp <- untangle.specials(Terms, 'strata', 1)
  3879.         stratx <- strata(m[temp$vars])
  3880.         }
  3881.     if (is.null(y)) y <- model.extract(m, 'response')
  3882.     }
  3883.     if (is.null(stratx)) stratx <- rep(1,n)
  3884.     ny <- ncol(y)
  3885.     if (nrow(y) != n) stop ("Mismatched lengths: logic error")
  3886.  
  3887.     type <- attr(y, 'type')
  3888.     if (type=='counting') {
  3889.     ord <- order(stratx, y[,2], -y[,3])
  3890.     if (method=='kaplan-meier')
  3891.           stop ("KM method not valid for counting type data")
  3892.     }
  3893.     else if (type=='right') {
  3894.     ord <- order(stratx, y[,1], -y[,2])
  3895.     y <- cbind(-1, y)
  3896.     }
  3897.     else stop("Cannot handle \"", type, "\" type survival data")
  3898.  
  3899.     if (length(strat)) {
  3900.     newstrat <- (as.numeric(stratx))[ord]
  3901.     newstrat <- as.integer(c(1*(diff(newstrat)!=0), 1))
  3902.     }
  3903.     else newstrat <- as.integer(c(rep(0,n-1),1))
  3904.  
  3905.     if ( !missing(newdata))
  3906.     stop("A newdata argument does not make sense for a null model")
  3907.  
  3908.     dimnames(y) <- NULL   #I only use part of Y, so names become invalid
  3909.     surv <- .C('agsurv2', as.integer(n),
  3910.               as.integer(0),
  3911.               y = y[ord,],
  3912.               score[ord],
  3913.               strata = newstrat,
  3914.               surv = double(n),
  3915.               varhaz = double(n),
  3916.               double(1),
  3917.               double(0),
  3918.               nsurv = as.integer(method=='kaplan-meier'),
  3919.               double(2),
  3920.               as.integer(1),
  3921.               double(1),
  3922.               newrisk= as.double(1))
  3923.     nsurv <- surv$nsurv
  3924.     ntime <- 1:nsurv
  3925.     tsurv <- surv$surv[ntime]
  3926.     tvar  <- surv$varhaz[ntime]
  3927.     if (surv$strata[1] <=1)
  3928.     temp _ list(time=surv$y[ntime,1],
  3929.          n.risk=surv$y[ntime,2],
  3930.          n.event=surv$y[ntime,3],
  3931.          surv=tsurv )
  3932.     else {
  3933.     temp <- surv$strata[1:(1+surv$strata[1])]
  3934.     tstrat <- diff(c(0, temp[-1])) #n in each strata
  3935.     names(tstrat) <- levels(stratx)
  3936.     temp _ list(time=surv$y[ntime,1],
  3937.          n.risk=surv$y[ntime,2],
  3938.          n.event=surv$y[ntime,3],
  3939.          surv=tsurv,
  3940.          strata= tstrat)
  3941.     }
  3942.     if (se.fit) temp$std.err <- sqrt(tvar)
  3943.  
  3944.     zval _ qnorm(1- (1-conf.int)/2, 0,1)
  3945.     if (conf.type=='plain') {
  3946.     temp1 <- temp$surv + zval* temp$std * temp$surv
  3947.     temp2 <- temp$surv - zval* temp$std * temp$surv
  3948.     temp <- c(temp, list(upper=pmin(temp1,1), lower=pmax(temp2,0),
  3949.             conf.type='plain', conf.int=conf.int))
  3950.     }
  3951.     if (conf.type=='log') {
  3952.     xx <- ifelse(temp$surv==0,1,temp$surv)  #avoid some "log(0)" messages
  3953.     temp1 <- ifelse(temp$surv==0, 0*temp$std, exp(log(xx) + zval* temp$std))
  3954.     temp2 <- ifelse(temp$surv==0, 0*temp$std, exp(log(xx) - zval* temp$std))
  3955.     temp <- c(temp, list(upper=pmin(temp1,1), lower=temp2,
  3956.             conf.type='log', conf.int=conf.int))
  3957.     }
  3958.     if (conf.type=='log-log') {
  3959.     who <- (temp$surv==0 | temp$surv==1) #special cases
  3960.     xx <- ifelse(who, .1,temp$surv)  #avoid some "log(0)" messages
  3961.     temp1 <- exp(-exp(log(-log(xx)) + zval*temp$std/log(xx)))
  3962.     temp1 <- ifelse(who, temp$surv + 0*temp$std, temp1)
  3963.     temp2 <- exp(-exp(log(-log(xx)) - zval*temp$std/log(xx)))
  3964.     temp2 <- ifelse(who, temp$surv + 0*temp$std, temp2)
  3965.     temp <- c(temp, list(upper=temp1, lower=temp2,
  3966.             conf.type='log-log', conf.int=conf.int))
  3967.     }
  3968.  
  3969.     temp$call <- call
  3970.     attr(temp, 'class') <- c("survfit.cox", "survfit")
  3971.     temp
  3972.     }
  3973. #SCCS @(#)survfit.coxph.s    4.15 06/17/93
  3974. survfit.coxph <-
  3975.   function(object, newdata, se.fit=T, conf.int=.95, individual=F,
  3976.         type=c('tsiatis', 'kaplan-meier'),
  3977.         conf.type=c('log', 'log-log', 'plain', 'none'))
  3978.          {
  3979.  
  3980.     if(!is.null((object$call)$weights))
  3981.     stop("Survfit cannot (yet) compute the result for a weighted model")
  3982.     call <- match.call()
  3983.     Terms <- terms(object)
  3984.     strat <- attr(Terms, "specials")$strata
  3985. ### <TSL> Not used
  3986. ###        resp <-  attr(Terms, "variables")[attr(Terms, "response")]
  3987.     n <- object$n
  3988.     nvar <- length(object$coef)
  3989.     score <- exp(object$linear.predictor)
  3990.     method <- match.arg(type)
  3991.     coxmethod <- object$method
  3992.     if (!se.fit) conf.type <- 'none'
  3993.     else conf.type <- match.arg(conf.type)
  3994.     if (length(strat)) temp <- untangle.specials(Terms, 'strata', 1)
  3995.  
  3996.     x <- object$x
  3997.     y <- object$y
  3998.     if (is.null(x) && (length(strat) || se.fit)) {  # I need both X and Y
  3999.     stratum <- object$strata
  4000.     m <- model.frame(object)
  4001.     if (is.null(x)) {   #Both strata and X will be null, or neither
  4002.         if (length(strat)) {
  4003.         x <- model.matrix("[.terms"(Terms,-temp$terms), m)[,-1,drop=F]
  4004.         stratum <- strata(m[temp$vars])
  4005.         }
  4006.         else {
  4007.         x <- model.matrix(Terms, m)[,-1,drop=F]
  4008.         stratum <- rep(1,n)
  4009.         }
  4010.         }
  4011.     if (is.null(y)) y <- model.extract(m, 'response')
  4012.     }
  4013.     else {
  4014.     y <- object$y
  4015.     if (is.null(y)) {
  4016.         m <- model.frame(object)
  4017.         y <- model.extract(m, 'response')
  4018.         }
  4019.     if (length(strat)) stratum <- object$strata
  4020.     else               stratum <- rep(1,n)
  4021.     }
  4022.     if (is.null(x)) x <- matrix(0,n,nvar)
  4023.  
  4024.     ny <- ncol(y)
  4025.     if (nrow(y) != n) stop ("Mismatched lengths: logic error")
  4026.     type <- attr(y, 'type')
  4027.     if (type=='counting') {
  4028.     ord <- order(stratum, y[,2], -y[,3])
  4029.     if (method=='kaplan-meier')
  4030.           stop ("KM method not valid for counting type data")
  4031.     }
  4032.     else if (type=='right') {
  4033.     ord <- order(stratum, y[,1], -y[,2])
  4034.     y <- cbind(-1, y)
  4035.     }
  4036.     else stop("Cannot handle \"", type, "\" type survival data")
  4037.  
  4038.     if (length(strat)) {
  4039.     newstrat <- (as.numeric(stratum))[ord]
  4040.     newstrat <- as.integer(c(1*(diff(newstrat)!=0), 1))
  4041.     }
  4042.     else newstrat <- as.integer(c(rep(0,n-1),1))
  4043.  
  4044.     if (individual && !missing(newdata)) stype <- 1
  4045.     else {
  4046.     stype <- 2
  4047.     if (length(strat)) Terms <- "[.terms"(Terms,-temp$terms)  #don't need it
  4048.     }
  4049.     offset2 <- mean(object$linear.predictors)
  4050.     if (!missing(newdata)) {
  4051.     m2 <- model.newframe(Terms, newdata, response=(stype==1))
  4052.     if (!inherits(m2, 'data.frame'))  {
  4053.         x2 <- as.matrix(m2)
  4054.         if (ncol(x2) != nvar) stop ("Wrong # of variables in new data")
  4055.         n2 <- nrow(x2)
  4056.         if (stype==1) stop("Program error #3")
  4057.         }
  4058.  
  4059.     else  {
  4060. ###        x2 <- model.matrix(Terms, m2)[,-1,drop=F]
  4061.         if (attr(attr(m2,"terms"),"response"))
  4062.           x2<-model.matrix(Terms,m2)[,-1,drop=F]
  4063.         else
  4064.           x2 <- model.matrix(delete.response(Terms), m2)[,-1,drop=F]
  4065. ###
  4066.         n2 <- nrow(x2)
  4067.         offset2 <- model.extract(m2, 'offset')
  4068.         if (is.null(offset2)) offset2 <- 0
  4069.         if (stype==1) {
  4070.         #
  4071.         # The case of an agreg, with a multiple line newdata
  4072.         #
  4073.         if (length(strat)) {
  4074.             strata2 <- factor(x2[,strat], levels=levels(stratum))
  4075.             x2 <- x2[, -strat, drop=F]
  4076.             }
  4077.         else strata2 <- rep(1, nrow(x2))
  4078.         y2 <- model.extract(m2, 'response')
  4079.         if (attr(y2,'type') != type)
  4080.             stop("Survival type of newdata does not match the fitted model")
  4081.         if (nrow(y2) != n2) stop("Wrong # of rows for Y")
  4082.         }
  4083.         }
  4084.     }
  4085.     else x2 <- matrix(object$means, nrow=1)
  4086.     n2 <- nrow(x2)
  4087.     coef <- ifelse(is.na(object$coef), 0, object$coef)
  4088.     newrisk <- exp(c(x2 %*% coef) + offset2 - sum(coef*object$means))
  4089.  
  4090.     dimnames(y) <- NULL   #I only use part of Y, so names become invalid
  4091.     if (stype==1) {
  4092.     surv <- .C("agsurv1", as.integer(n),
  4093.                  as.integer(nvar),
  4094.                  y[ord,],
  4095.                  score,
  4096.                  strata=newstrat,
  4097.                  surv=double(n*n2),
  4098.                  varh=double(n*n2),
  4099.                  nsurv=as.integer(2+ 1*(coxmethod=='efron')),
  4100.                  x[ord,],
  4101.                  double(3*nvar),
  4102.                  object$var,
  4103.                  y = double(3*n*n2),
  4104.                  as.integer(n2),
  4105.                  y2,
  4106.                  x2,
  4107.                  newrisk,
  4108.                  as.integer(strata2) )
  4109.     ntime <- 1:surv$nsurv
  4110.     temp <- (matrix(surv$y, ncol=3))[ntime,]
  4111.     temp <- list(time = temp[,1],
  4112.              n.risk= temp[,2],
  4113.              n.event=temp[,3],
  4114.              surv = surv$surv[ntime])
  4115.     if (se.fit) temp$std.err <- sqrt(surv$varh[ntime])
  4116.     }
  4117.     else {
  4118.     temp <- ifelse(method=='kaplan-meier', 1,
  4119.                     2+as.integer(coxmethod=='efron'))
  4120.     surv <- .C('agsurv2', as.integer(n),
  4121.                   as.integer(nvar* se.fit),
  4122.                   y = y[ord,],
  4123.                   score[ord],
  4124.                   strata = newstrat,
  4125.                   surv = double(n*n2),
  4126.                   varhaz = double(n*n2),
  4127.                   x[ord,],
  4128.                   object$var,
  4129.                   nsurv = as.integer(temp),
  4130.                   double(3*nvar),
  4131.                   as.integer(n2),
  4132.                   x2,
  4133.                   newrisk)
  4134.     nsurv <- surv$nsurv
  4135.     ntime <- 1:nsurv
  4136.     if (n2>1) {
  4137.         tsurv <- matrix(surv$surv[1:(nsurv*n2)], ncol=n2)
  4138.         tvar  <- matrix(surv$varhaz[1:(nsurv*n2)], ncol=n2)
  4139.         dimnames(tsurv) <- list(NULL, dimnames(x2)[[1]])
  4140.         }
  4141.     else {
  4142.         tsurv <- surv$surv[ntime]
  4143.         tvar  <- surv$varhaz[ntime]
  4144.         }
  4145.     if (surv$strata[1] <=1)
  4146.         temp _ list(time=surv$y[ntime,1],
  4147.              n.risk=surv$y[ntime,2],
  4148.              n.event=surv$y[ntime,3],
  4149.              surv=tsurv )
  4150.     else {
  4151.         temp <- surv$strata[1:(1+surv$strata[1])]
  4152.         tstrat <- diff(c(0, temp[-1])) #n in each strata
  4153.         names(tstrat) <- levels(stratum)
  4154.         temp _ list(time=surv$y[ntime,1],
  4155.              n.risk=surv$y[ntime,2],
  4156.              n.event=surv$y[ntime,3],
  4157.              surv=tsurv,
  4158.              strata= tstrat)
  4159.         }
  4160.     if (se.fit) temp$std.err <- sqrt(tvar)
  4161.     }
  4162.  
  4163.     zval _ qnorm(1- (1-conf.int)/2, 0,1)
  4164.     if (conf.type=='plain') {
  4165.     temp1 <- temp$surv + zval* temp$std * temp$surv
  4166.     temp2 <- temp$surv - zval* temp$std * temp$surv
  4167.     temp <- c(temp, list(upper=pmin(temp1,1), lower=pmax(temp2,0),
  4168.             conf.type='plain', conf.int=conf.int))
  4169.     }
  4170.     if (conf.type=='log') {
  4171.     xx <- ifelse(temp$surv==0,1,temp$surv)  #avoid some "log(0)" messages
  4172.     temp1 <- ifelse(temp$surv==0, 0*temp$std, exp(log(xx) + zval* temp$std))
  4173.     temp2 <- ifelse(temp$surv==0, 0*temp$std, exp(log(xx) - zval* temp$std))
  4174.     temp <- c(temp, list(upper=pmin(temp1,1), lower=temp2,
  4175.             conf.type='log', conf.int=conf.int))
  4176.     }
  4177.     if (conf.type=='log-log') {
  4178.     who <- (temp$surv==0 | temp$surv==1) #special cases
  4179.     xx <- ifelse(who, .1,temp$surv)  #avoid some "log(0)" messages
  4180.     temp1 <- exp(-exp(log(-log(xx)) + zval*temp$std/log(xx)))
  4181.     temp1 <- ifelse(who, temp$surv + 0*temp$std, temp1)
  4182.     temp2 <- exp(-exp(log(-log(xx)) - zval*temp$std/log(xx)))
  4183.     temp2 <- ifelse(who, temp$surv + 0*temp$std, temp2)
  4184.     temp <- c(temp, list(upper=temp1, lower=temp2,
  4185.             conf.type='log-log', conf.int=conf.int))
  4186.     }
  4187.  
  4188.     temp$call <- call
  4189.     attr(temp, 'class') <- c("survfit.cox", "survfit")
  4190.     temp
  4191.     }
  4192. #SCCS @(#)survfit.km.s    4.12 09/17/96
  4193. survfit.km <- function(x, y, casewt=rep(1,n),
  4194.         type=c('kaplan-meier', 'fleming-harrington', 'fh2'),
  4195.         error=c('greenwood', "tsiatis"), se.fit=T,
  4196.         conf.int= .95,
  4197.         conf.type=c('log',  'log-log',  'plain', 'none'),
  4198.         conf.lower=c('usual', 'peto', 'modified'))
  4199.     {
  4200.     type <- match.arg(type)
  4201.     method <- match(type, c("kaplan-meier", "fleming-harrington", "fh2"))
  4202.  
  4203.     error <- match.arg(error)
  4204.     error.int <- match(error, c("greenwood", "tsiatis"))
  4205.     conf.type <- match.arg(conf.type)
  4206.     conf.lower<- match.arg(conf.lower)
  4207.  
  4208.     ny <- ncol(y)
  4209.     n <- nrow(y)
  4210.  
  4211.     if (!is.Surv(y)) stop("y must be a Surv object")
  4212.     if (!is.factor(x)) stop("x must be a factor")
  4213.     if (attr(y, 'type') != 'right') stop("Can only handle right censored data")
  4214.  
  4215.     sorted <- (1:n)[order(x, y[,ny-1])]
  4216.     y <- y[sorted,]
  4217.     newstrat <- as.numeric(x[sorted])
  4218.     newstrat <- as.integer(c(1*(diff(newstrat)!=0), 1))
  4219.     if (sum(newstrat) > n/2)
  4220.     stop("Number of strata > number of observations/2")
  4221.     if (method==3 && any(floor(casewt) != casewt))
  4222.     stop("The fh2 method is not valid for fractional case weights")
  4223.  
  4224.     storage.mode(y) <- "double"
  4225.     dimnames(y) <- NULL
  4226.     surv <- .C("survfit2", as.integer(n),
  4227.               y = y,
  4228.               as.integer(ny),
  4229.               as.double(casewt[sorted]),
  4230.               strata= as.integer(newstrat),
  4231.               nstrat= as.integer(method),
  4232.               as.integer(error.int),
  4233.               mark=double(n),
  4234.               surv=double(n),
  4235.               varhaz=double(n),
  4236.               risksum=double(n),
  4237.               ntime = integer(1))
  4238.     ntime <- surv$ntime
  4239.     if (error.int==1) surv$varhaz[surv$surv==0] <- NA
  4240.     ntime <- 1:ntime
  4241.     if (surv$nstrat ==1)
  4242.     temp _ list(time=surv$y[ntime,1],
  4243.          n.risk=surv$risksum[ntime],
  4244.          n.event=surv$mark[ntime],
  4245.          surv=surv$surv[ntime])
  4246.     else {
  4247.     temp <- surv$strata[1:surv$nstrat]
  4248.     tstrat <- diff(c(0, temp)) #n in each strata
  4249.     names(tstrat) <- levels(x)
  4250.     temp _ list(time=surv$y[ntime,1],
  4251.          n.risk=surv$risksum[ntime],
  4252.          n.event=surv$mark[ntime],
  4253.          surv=surv$surv[ntime],
  4254.          strata= tstrat)
  4255.     }
  4256.  
  4257.     if (se.fit) {
  4258.     std.err <- sqrt(surv$varhaz[ntime])
  4259.     temp$std.err <- std.err
  4260.     events <- temp$n.event >0
  4261.     n.lag <- rep(c(temp$n.risk[1], temp$n.risk[events]),
  4262.                   diff(c(ntime[1], ntime[events], 1+max(ntime))))
  4263.     std.low <- switch(conf.lower,
  4264.             'usual'   = std.err,
  4265.             'peto'    = sqrt((1-temp$surv)/ temp$n.risk),
  4266.             'modified'= std.err * sqrt(n.lag/temp$n.risk)
  4267.             )
  4268.     zval _ qnorm(1- (1-conf.int)/2, 0,1)
  4269.     if (conf.type=='plain') {
  4270.         temp1 <- temp$surv + zval* std.err * temp$surv
  4271.         temp2 <- temp$surv - zval* std.low * temp$surv
  4272.         temp <- c(temp, list(upper=pmin(temp1,1), lower=pmax(temp2,0),
  4273.                 conf.type='plain', conf.int=conf.int))
  4274.         }
  4275.     if (conf.type=='log') {
  4276.         xx <- ifelse(temp$surv==0,1,temp$surv)  #avoid some "log(0)" messages
  4277.         temp1 <- ifelse(temp$surv==0, NA, exp(log(xx) + zval* std.err))
  4278.         temp2 <- ifelse(temp$surv==0, NA, exp(log(xx) - zval* std.low))
  4279.         temp <- c(temp, list(upper=pmin(temp1,1), lower=temp2,
  4280.                 conf.type='log', conf.int=conf.int))
  4281.         }
  4282.     if (conf.type=='log-log') {
  4283.         who <- (temp$surv==0 | temp$surv==1) #special cases
  4284.         temp3 <- ifelse(temp$surv==0, NA, 1)
  4285.         xx <- ifelse(who, .1,temp$surv)  #avoid some "log(0)" messages
  4286.         temp1 <- exp(-exp(log(-log(xx)) + zval*std.err/log(xx)))
  4287.         temp1 <- ifelse(who, temp3, temp1)
  4288.         temp2 <- exp(-exp(log(-log(xx)) - zval*std.low/log(xx)))
  4289.         temp2 <- ifelse(who, temp3, temp2)
  4290.         temp <- c(temp, list(upper=temp1, lower=temp2,
  4291.                 conf.type='log-log', conf.int=conf.int))
  4292.         }
  4293.     }
  4294.     temp
  4295.     }
  4296. #SCCS 05/23/95 @(#)survfit.s    4.7
  4297. survfit <- function (formula, data, weights, subset, na.action, ...) {
  4298.     call <- match.call()
  4299.     # Real tricky -- find out if the first arg is "Surv(...)" without
  4300.     #  evaluating it.  If this is so, or it is a survival object, turn it
  4301.     #  into a formula
  4302. ###<TSL> even trickier in R
  4303. ###    if ((mode(call[[2]]) == 'call' &&  call[[2]][[1]] == as.name('Surv')) || inherits(formula, 'Surv'))  
  4304. ###
  4305.     if (((mode(call[[2]])=="call") &&  as.character(call[[2]][[1]])=="Surv") || inherits(formula,'Surv'))
  4306. {
  4307.     # The dummy function stops an annoying warning message "Looking for
  4308.     #  'formula' of mode function, ignored one of mode ..."
  4309.     ###<TSL> except that it doesn't in R
  4310.     xx <- function(x) formula(x)
  4311.     formula <- xx(paste(deparse(call[[2]]), 1, sep="~"))
  4312.     }
  4313.  
  4314.     if (!inherits(formula, 'formula')) {
  4315.       ### Rchange
  4316.       temp <- MyUseMethod("survfit",formula)
  4317.     }
  4318.     else {
  4319.     m <- match.call(expand=F)
  4320.     m$... <- NULL
  4321.  
  4322.     Terms <- terms(formula, 'strata')
  4323.     ord <- attr(Terms, 'order')
  4324.     if (length(ord) & any(ord !=1))
  4325.         stop("Interaction terms are not valid for this function")
  4326.     m$formula <- Terms
  4327.     m[[1]] <- as.name("model.frame")
  4328.     m <- eval(m, sys.parent())
  4329.  
  4330.     n <- nrow(m)
  4331.     Y <- model.extract(m, response)
  4332.     casewt <- model.extract(m, "weights")
  4333.     # The second line below works around a bug in Splus 3.0.1, which later
  4334.     #    went away, i.e., casewt is returned as an unevaluated arg.
  4335.     if (is.null(casewt)) casewt <- rep(1,n)
  4336.     else if (mode(casewt)=='argument') casewt <- eval(casewt[[1]])
  4337.  
  4338.     if (!is.null(attr(Terms, 'offset'))) warning("Offset term ignored")
  4339.  
  4340.     ll <- attr(Terms, 'term.labels')
  4341.     if (length(ll) == 0) X <- factor(rep(1,n))
  4342.     else {
  4343.         temp <-  rep(1, length(ll))
  4344.         strat <- untangle.specials(Terms, 'strata',1)$terms
  4345.         if (length(strat)) temp[strat] <- 0
  4346.         lname <- ifelse(temp==1, paste(ll,'=', sep=''), "")
  4347.         temp <- paste("'",lname, "', ","as.character(m[['", ll, "']])", sep='')
  4348.         temp <- paste(temp, collapse=", ', ',")
  4349.         temp <- paste("paste(", temp, ",sep='')")
  4350. ## Rchange added [[1]]
  4351.         X <- factor(eval(parse(text=temp)[[1]]))
  4352.         }
  4353.  
  4354.     temp <- survfit.km(X, Y, casewt, ...)
  4355.     attr(temp, "class") <- "survfit"
  4356.     if (!is.null(attr(m, 'na.action'))) temp$na.action <- attr(m, 'na.action')
  4357.     }
  4358.     temp$call <- call
  4359.     temp
  4360.     }
  4361.  
  4362. # The subscript function is bundled in here, although used most
  4363. #  often in plotting
  4364.  
  4365. "[.survfit" <- function(fit,i,j, drop=F) {
  4366.     if (is.null(fit$strata)) {
  4367.     if (is.matrix(fit$surv)) {
  4368.         fit$surv <- fit$surv[,i,drop=drop]
  4369.         if (!is.null(fit$std.err)) fit$std.err <- fit$std.err[,i,drop=drop]
  4370.         if (!is.null(fit$upper)) fit$upper <- fit$upper[,i,drop=drop]
  4371.         if (!is.null(fit$lower)) fit$lower <- fit$lower[,i,drop=drop]
  4372.         }
  4373.     else warning("Survfit object has only a single survival curve")
  4374.     }
  4375.     else {
  4376.     if (missing(i)) keep <- seq(along=fit$time)
  4377.     else {
  4378.         if (is.character(i)) strat <- rep(names(fit$strata), fit$strata)
  4379.         else                 strat <- rep(1:length(fit$strata), fit$strata)
  4380.         keep <- seq(along=strat)[match(strat, i, nomatch=0)>0]
  4381.         fit$strata  <- fit$strata[i]
  4382.         fit$time    <- fit$time[keep]
  4383.         fit$n.risk  <- fit$n.risk[keep]
  4384.         fit$n.event <- fit$n.event[keep]
  4385.         }
  4386.     if (is.matrix(fit$surv)) {
  4387.         if (missing(j)) {
  4388.         fit$surv <- fit$surv[keep,drop=drop]
  4389.         if (!is.null(fit$std.err)) fit$std.err <- fit$std.err[keep,drop=drop]
  4390.         if (!is.null(fit$upper)) fit$upper <- fit$upper[keep,drop=drop]
  4391.         if (!is.null(fit$lower)) fit$lower <- fit$lower[keep,drop=drop]
  4392.         }
  4393.         else {
  4394.         fit$surv <- fit$surv[keep,j]
  4395.         if (!is.null(fit$std.err)) fit$std.err <- fit$std.err[keep,j]
  4396.         if (!is.null(fit$upper)) fit$upper <- fit$upper[keep,j]
  4397.         if (!is.null(fit$lower)) fit$lower <- fit$lower[keep,j]
  4398.         }
  4399.         }
  4400.     else {
  4401.         fit$surv <- fit$surv[keep]
  4402.         if (!is.null(fit$std.err)) fit$std.err <- fit$std.err[keep]
  4403.         if (!is.null(fit$upper)) fit$upper <- fit$upper[keep]
  4404.         if (!is.null(fit$lower)) fit$lower <- fit$lower[keep]
  4405.         }
  4406.     }
  4407.     fit
  4408.     }
  4409.  
  4410. # SCCS  @(#)survobrien.s    4.3 04/14/92
  4411. #
  4412. # The test for survival proposed by Peter O'Brien
  4413. #
  4414. survobrien <- function(formula, data= sys.parent()) {
  4415.     m <- model.frame(formula, data, na.action= function(x) x )
  4416.     n <- nrow(m)
  4417.     Terms <- attr(m, 'terms')
  4418.  
  4419.     y <- model.extract(m, 'response')
  4420.     if (!inherits(y, "Surv")) stop ("Response must be a survival object")
  4421.     if (attr(y, 'type') != 'right') stop("Can only handle right censored data")
  4422.  
  4423.     # Figure out which are the continuous predictor variables
  4424.     m.name <- names(m)
  4425.     temp <- match(attr(Terms, 'term.labels'), m.name)
  4426.     cont <- NULL
  4427.     for (i in temp) {if (!is.factor(m[[i]])) cont <- c(cont, i)}
  4428.     if (is.null(cont)) stop ("No continuous variables to modify")
  4429.  
  4430.     keepers <- rep(T, length(m))  #The ones to be kept "as is"
  4431.     keepers[cont] <- F
  4432.     keepers[attr(Terms, 'response')] <- F
  4433.     ord <- order(y[,1])
  4434.     x <- as.matrix(m[ord, cont])
  4435.     time <- y[ord,1]
  4436.     status <- y[ord,2]
  4437.     nvar <- length(cont)
  4438.  
  4439.     nline <- 0
  4440.     for (i in unique(time[status==1])) nline <- nline + sum(time >=i)
  4441.     start <- stop <- event <- double(nline)
  4442.     xx <- matrix(double(nline*nvar), ncol=nvar)
  4443.     ltime <- 0
  4444.     j<- 1
  4445.     keep.index <- NULL
  4446.     for (i in unique(time[status==1])) {
  4447.     who <- (time >=i)
  4448.     nrisk <- sum(who)
  4449.     if (nrisk<2) break
  4450.     temp <- apply(x[who,,drop=F], 2, rank)
  4451.     temp <- (2*temp -1)/ (2* nrisk)   #percentiles
  4452.     logit<- log(temp/(1-temp))           #logits
  4453.     deaths <- (status[who]==1 & time[who]==i)
  4454.  
  4455.     k <- seq(from=j, length=nrisk)
  4456.     start[k] <- ltime
  4457.     stop[k] <-  i
  4458.     event[k] <- deaths
  4459.     xx[k,] <- logit
  4460.     j <- j + nrisk
  4461.     ltime <- i
  4462.     keep.index <- c(keep.index, ord[who])
  4463.     }
  4464.  
  4465.     if (any(keepers)) {
  4466.      temp <- list(m[keep.index, keepers], start, stop, event, xx)
  4467.      names(temp) <- c(m.name[keepers], "start", "stop", "event",
  4468.                 m.name[cont])
  4469.      }
  4470.     else {
  4471.     temp <- list(start, stop, event, xx)
  4472.     names(temp) <- c(m.name[keepers], "start", "stop", "event",
  4473.                 m.name[cont])
  4474.     }
  4475.     temp
  4476.     }
  4477. #SCCS @(#)survreg.control.s    4.1 11/19/92
  4478. survreg.control <- function(maxiter=30, rel.tolerance=1e-5, failure=1)
  4479.     list(maxiter = maxiter, rel.tolerance = rel.tolerance, failure =failure)
  4480. # SCCS @(#)survreg.distributions.s    4.3 11/19/92
  4481. #
  4482. # Create the survreg.distributions object
  4483. #
  4484. ###<TSL> can't use quotes for names in list()
  4485. survreg.distributions <- list(
  4486. extreme = list(
  4487.     name = "Extreme value",
  4488.     parms = list(scale=1),
  4489.     logconcave = T,
  4490.     init  = function(x,fixed, init) {
  4491.             if (!is.null(fixed$scale))
  4492.                 temp<- c(log(fixed$scale), 1)
  4493.             else if(!is.null(init$scale))
  4494.                 temp<- c(log(init$scale), 0)
  4495.             else    temp<- c(log(mean(x^2)/1.3)/2 ,0)
  4496.             matrix(temp, nrow=1, dimnames=list("Log(scale)", NULL))
  4497.             },
  4498.     deviance= function(y, parms, loglik) {
  4499.             status <- y[,ncol(y)]
  4500.             scale <- exp(parms[1])
  4501.             if (any(status==3)) {
  4502.                 temp <- ifelse(status==3,(y[,2] - y[,1])/scale,1)
  4503.                 temp2 <- temp/(exp(temp)-1)
  4504.                 temp3 <- log(exp(-temp2) - exp(-temp2*exp(temp)))
  4505.                 best <- ifelse(status==1, -(1+log(scale)),
  4506.                     ifelse(status==3, temp3, 0))
  4507.                 }
  4508.             else best <- ifelse(status==1, -(1+log(scale)), 0)
  4509.             2*(best-loglik)
  4510.             },
  4511.     print = function(parms, fixed)
  4512.         if (fixed)
  4513.              paste("Dispersion (scale) fixed at", format(exp(parms)))
  4514.         else paste("Dispersion (scale) =",
  4515.                            format(exp(parms)))
  4516.     ),
  4517.  
  4518. logistic = list(
  4519.     name  = "Logistic",
  4520.     parms = list(scale=1),
  4521.     logconcave = T,
  4522.     init  = function(x,fixed, init) {
  4523.             if (!is.null(fixed$scale))
  4524.                 temp<- c(log(fixed$scale), 1)
  4525.             else if(!is.null(init$scale))
  4526.                 temp<- c(log(init$scale), 0)
  4527.             else    temp<- c(log(mean(x^2)/2)/2 ,0)
  4528.             matrix(temp, nrow=1, dimnames=list("Log(scale)", NULL))
  4529.             },
  4530.     deviance= function(y, parms, loglik) {
  4531.             status <- y[,ncol(y)]
  4532.             scale <- exp(parms[1])
  4533.             if (any(status==3)) {
  4534.                 temp <- ifelse(status==3,(y[,2] - y[,1])/scale,1)
  4535.                 temp <- (y[,2] - y[,1])/scale
  4536.                 temp2 <- exp(temp/2)
  4537.                 temp3 <- log((temp2-1)/(temp2+1))
  4538.                 best <- ifelse(status==1, -log(4*scale),
  4539.                     ifelse(status==3, temp3, 0))
  4540.                 }
  4541.             else best <- ifelse(status==1, -log(4*scale), 0)
  4542.             2*(best-loglik)
  4543.             },
  4544.     print = function(parms, fixed)
  4545.         if (fixed)
  4546.              paste("Dispersion (scale) fixed at", format(exp(parms)))
  4547.         else paste("Dispersion (scale) est =",
  4548.                            format(exp(parms)))
  4549.     ),
  4550.  
  4551. gaussian = list(
  4552.     name  = "Gaussian",
  4553.     parms = list(scale=1),
  4554.     logconcave = T,
  4555.     init  = function(x,fixed, init) {
  4556.             if (!is.null(fixed$scale))
  4557.                 temp<- c(log(fixed$scale), 1)
  4558.             else if(!is.null(init$scale))
  4559.                 temp<- c(log(init$scale), 0)
  4560.             else    temp<- c(log(mean(x^2))/2 ,0)
  4561.             matrix(temp, nrow=1, dimnames=list("Log(scale)", NULL))
  4562.             },
  4563.     deviance= function(y, parms, loglik) {
  4564.             status <- y[,ncol(y)]
  4565.             scale <- exp(parms[1])
  4566.             temp <-  ifelse(status==3, (y[,2] - y[,1])/scale, 1)
  4567.             temp2 <- 2*(pnorm(temp/2) -.5)
  4568.             best <- ifelse(status==1, -log(sqrt(2*pi)*scale),
  4569.                 ifelse(status==3, temp2, 0))
  4570.             2*(best-loglik)
  4571.             },
  4572.     print = function(parms, fixed)
  4573.         if (fixed)
  4574.              paste("Dispersion (scale) fixed at", format(exp(parms)))
  4575.         else paste("Dispersion (scale) =",
  4576.                            format(exp(parms)))
  4577.     ),
  4578.  
  4579. t = list(
  4580.     name  = "Student-t",
  4581.     parms = list(scale=1, df=2),
  4582.     logconcave = F,
  4583.     init  = function(x,fixed, init) {
  4584.             if (!is.null(fixed$scale))
  4585.                 temp<- c(log(fixed$scale), 1)
  4586.             else if(!is.null(init$scale))
  4587.                 temp<- c(log(init$scale), 0)
  4588.             else    temp<- c(log(mean(x^2))/2 ,0)
  4589.  
  4590.             if (!is.null(fixed$df))
  4591.                 temp<- c(temp, fixed$df, 1)
  4592.             else if(!is.null(init$df))
  4593.                 temp<- c(temp, init$df, 0)
  4594.             else    {
  4595.                 k <- mean(x^4)/ (3*temp[1])
  4596.                 df<- (3*k + sqrt(8*k + k^2))/(16*k*(k-1))
  4597.                 temp<- c(temp, df, 0)
  4598.                 }
  4599.  
  4600.             matrix(temp, nrow=2, byrow=T,
  4601.                 dimnames=list(c("Log(scale)", "df"),  NULL))
  4602.             },
  4603.     deviance= function(y, parms, loglik) {
  4604.             status <- y[,ncol(y)]
  4605.             scale <- exp(parms[1])
  4606.             df <- parms[2]
  4607.             temp <-  ifelse(status==3, (y[,2] - y[,1])/scale, 1)
  4608.             temp2 <- 2*(pt(temp/2, df) -.5)
  4609.             temp3 <- lgamma((df+1)/2) -
  4610.                     (lgamma(df/2) + .5*log(pi*df*scale^2))
  4611.             best <- ifelse(status==1, temp3,
  4612.                 ifelse(status==3, temp2, 0))
  4613.             2*(best-loglik)
  4614.             },
  4615.     print = function(parms, fixed) {
  4616.         tt <- if (fixed[1])
  4617.              paste("Dispersion (scale) fixed at", format(exp(parms[1])))
  4618.         else paste("Dispersion (scale) =",
  4619.                            format(exp(parms[1])))
  4620.         if (fixed[2]) paste(tt, ", df fixed at", format(parms[2]))
  4621.         else tt
  4622.         }
  4623.     )
  4624.  )
  4625. #SCCS @(#)survreg.fit.s    4.8 12/29/92
  4626. #
  4627. # This handles the one parameter distributions-- extreme, logistic,
  4628. #       gaussian, and cauchy.
  4629. # The parent routine survreg can't allow Cauchy.  It gives negative weights
  4630. #   when we try to fit it into the IRLS model, as Cauchy is not log-covex.
  4631. #
  4632. survreg.fit<- function(x, y, offset, init, controlvals, dist, fixed,
  4633.                 nullmodel=T) {
  4634.  
  4635.     iter.max <- controlvals$maxiter
  4636.     eps <- controlvals$rel.tol
  4637.  
  4638.     if (!is.matrix(x)) stop("Invalid X matrix ")
  4639.     n <- nrow(x)
  4640.     nvar <- ncol(x)
  4641.     ny <- ncol(y)
  4642.     if (is.null(offset)) offset <- rep(0,n)
  4643.  
  4644.     sd <- survreg.distributions[[dist]]
  4645.     if (is.null(sd)) stop ("Unrecognized distribution")
  4646.     dnum <- match(dist, c("extreme", "logistic", "gaussian", "cauchy"))
  4647.     if (is.na(dnum)) stop ("Unknown distribution given")
  4648.  
  4649.     ncol.deriv <- if (any(y[,ny]==3)) 6  else 3
  4650.     nvar2 <- nvar + length(sd$parms) - length(fixed)
  4651.     yy <- ifelse(y[,ny]!=3, y[,1], (y[,1]+y[,2])/2 )
  4652.  
  4653.     if (is.numeric(init)) {
  4654.     if (length(init) != nvar2) stop("Wrong length for initial parameters")
  4655.     eta <- x %*% init[1:nvar]
  4656.     tfix <- sd$init(yy - eta, fixed, init)
  4657.     }
  4658.     else {
  4659.     if (is.null(eta <- init$eta))  eta <- mean(yy)
  4660.     else if (length(eta) != n) stop ("Wrong length for init$eta")
  4661.  
  4662.     # Do the 'glim' method of finding an initial value of coef,
  4663.     tfix <- sd$init(yy - (eta+offset), init, fixed)
  4664.     deriv <- .C("survreg_g",
  4665.                as.integer(n),
  4666.                y,
  4667.                as.integer(ny),
  4668.                as.double(eta + offset),
  4669.                coef= as.double(c(0,tfix[,1])),
  4670.                deriv = matrix(double(n * 3),nrow=n),
  4671.                as.integer(3),
  4672.                as.integer(dnum))$deriv
  4673.     wt <-  -1*deriv[,3]
  4674.     coef <- solve(t(x)%*% (wt*x), c((wt*eta + deriv[,2])%*% x))
  4675.     eta <- x %*% coef  + offset
  4676.     tfix <- sd$init(yy-eta, fixed, init)
  4677.     init <- c(coef, tfix[tfix[,2]==0,1])
  4678.     }
  4679.  
  4680.     fit <- .C("survreg",
  4681.            iter = as.integer(iter.max),
  4682.            as.integer(n),
  4683.            as.integer(nvar),
  4684.            y,
  4685.            as.integer(ny),
  4686.            x,
  4687.            as.double(offset),
  4688.            coef= as.double(init),
  4689.            as.integer(nrow(tfix)),
  4690.            tfix,
  4691.            double(3*(nvar2) + 2*n),
  4692.            imat= matrix(0, nvar2, nvar2),
  4693.            loglik=double(2),
  4694.            flag=integer(1),
  4695.            as.double(eps),
  4696.            deriv = matrix(double(ncol.deriv*n),nrow=n),
  4697.            as.integer(dnum))
  4698.  
  4699.     if (iter.max >1 && fit$flag== -1) {
  4700.     if (controlvals$failure==1)
  4701.            warning("Ran out of iterations and did not converge")
  4702.     else if (controlvals$failure==2)
  4703.            return("Ran out of iterations and did not converge")
  4704.     }
  4705.  
  4706.     temp <- dimnames(x)[[2]]
  4707.     if (is.null(temp)) temp <- paste("x", 1:ncol(x))
  4708.     temp <- c(temp, (dimnames(tfix)[[1]])[tfix[,2]==0])
  4709.     dimnames(fit$imat) <- list(temp, temp)
  4710.     names(fit$coef) <- temp
  4711.     parms <- tfix[,1]
  4712.     parms[tfix[,2]==0] <- fit$coef[-(1:nvar)]
  4713.  
  4714.     if (!nullmodel)
  4715.     c(fit[c("iter", "coef", "imat", "loglik", "flag", "deriv")],
  4716.         list(parms=parms, fixed=tfix[,2]==1))
  4717.     else {
  4718.     init <- c(mean(x%*% fit$coef[1:nvar]), fit$coef[-(1:nvar)])
  4719.     temp <- cbind(parms, 1)     # "nail down" extras
  4720.     nfit <- .C("survreg",
  4721.            iter = as.integer(iter.max),
  4722.            as.integer(n),
  4723.            nvar= as.integer(1),
  4724.            y,
  4725.            as.integer(ny),
  4726.            x= rep(1,n),
  4727.            as.double(offset),
  4728.            coef= as.double(init),
  4729.            as.integer(nrow(tfix)),
  4730.            temp,
  4731.            double(3*(nvar) + 2*n),
  4732.            imat= matrix(0, nvar, nvar),
  4733.            loglik=double(2),
  4734.            flag=integer(1),
  4735.            as.double(eps),
  4736.            deriv = matrix(double(ncol.deriv*n),nrow=n),
  4737.            as.integer(dnum))
  4738.  
  4739.     c(fit[c("iter", "coef", "imat", "loglik", "flag", "deriv")],
  4740.            list(ndev=nfit$loglik, ncoef=nfit$coef, parms=parms,
  4741.             fixed=tfix[,2]==1))
  4742.     }
  4743.     }
  4744. #SCCS @(#)survreg.s    4.15 02/04/95
  4745. survreg <- function(formula=formula(data), data=sys.parent(),
  4746.     subset, na.action,
  4747.     link='log',
  4748.     dist=c("extreme", "logistic", "gaussian", "exponential",
  4749.            "rayleigh"),
  4750.     init=NULL,  fixed=list(), control,
  4751.     model=F, x=F, y=T, ...) {
  4752.  
  4753.     call <- match.call()
  4754.     m <- match.call(expand=F)
  4755.     m$dist <- m$link <- m$model <- m$x <- m$y <- m$... <-  NULL
  4756.     m$start <- m$fixed <- m$control <- m$init <- NULL
  4757.     m[[1]] <- as.name("model.frame")
  4758.     m <- eval(m, sys.parent())
  4759.     Terms <- attr(m, 'terms')
  4760.  
  4761.     dist <- match.arg(dist)
  4762. ##    lnames <- dimnames(glm.links)[[2]]
  4763. ##    link <- pmatch(link, lnames, 0)
  4764.     link<-make.link(link)
  4765. ##    if (link==0) stop("Invalid link function")
  4766. ##    else link <- lnames[link]
  4767.  
  4768.     Y <- model.extract(m, "response")
  4769.     if (!inherits(Y, "Surv")) stop("Response must be a survival object")
  4770.     X <- model.matrix(Terms, m)
  4771.     n <- nrow(X)
  4772.     nvar <- ncol(X)
  4773.     offset<- attr(Terms, "offset")
  4774.     if (!is.null(offset)) offset <- as.numeric(m[[offset]])
  4775.     else                  offset <- rep(0, n)
  4776.  
  4777.     type <- attr(Y, "type")
  4778. ##    linkfun <- glm.links["link", link][[1]]
  4779.     linkfun<-link$linkfun
  4780.     if (type== 'counting') stop ("Invalid survival type")
  4781.     else if (type=='interval') {
  4782.     if (any(Y[,3]==3))
  4783.          Y <- cbind(linkfun(Y[,1:2]), Y[,3])
  4784.     else Y <- cbind(linkfun(Y[,1]), Y[,3])
  4785.     }
  4786.     else if (type=='left')
  4787.          Y <- cbind(linkfun(Y[,1]), 2-Y[,2])
  4788.     else     Y <- cbind(linkfun(Y[,1]), Y[,2])
  4789.  
  4790.     controlvals <- survreg.control()
  4791.     if (!missing(control)) 
  4792.     controlvals[names(control)] <- control
  4793.  
  4794.     if( dist=="exponential") {
  4795.     fixed$scale <- 1
  4796.     dist <- 'extreme'
  4797.     }
  4798.     else if (dist=="rayleigh") {
  4799.     fixed$scale <- .5
  4800.     dist <- 'extreme'
  4801.     }
  4802.  
  4803.     sd <- survreg.distributions[[dist]]
  4804.     if (length(fixed)>0) {
  4805.     ifix <- match(names(fixed), names(sd$parms), nomatch=0)
  4806.     if (any(ifix==0))
  4807.         stop (paste("Parameter(s)", paste(names(fixed)[ifix==0]),
  4808.             "in the fixed list not valid for this dist"))
  4809.     }
  4810.     if (is.list(init) && length(init)>0) {
  4811.     ifix <- match(names(init), c('eta',names(sd$parms)), nomatch=0)
  4812.     if (any(ifix==0))
  4813.         stop (paste("Parameter(s)", paste(names(init)[ifix==0]),
  4814.             "in the init list not valid for this dist"))
  4815.     }
  4816.  
  4817.  
  4818.     sfit <- survreg.fit(X, Y, offset, init=init, controlvals=controlvals,
  4819.             dist= dist, fixed=fixed)
  4820.     if (is.character(sfit))  fit <- list(fail=sfit)  #error message
  4821.     else {
  4822.     # There may be more clever ways to do this, but ....
  4823.     #  In order to make it look like IRLS, and get all the components
  4824.     #  that I need for glm inheritance, do one step of weighted least
  4825.     #  squares.
  4826.     eta <- c(X %*% sfit$coef[1:nvar]) + offset
  4827.     wt<- -sfit$deriv[,3]
  4828. ###    fit <- lm.wfit(X, eta + sfit$deriv[,2]/wt, wt, "qr", ...)
  4829.     fit <- lm.w.fit(X, eta + sfit$deriv[,2]/wt, wt)
  4830. ###    ifun <- glm.links['inverse',link][[1]]
  4831.     ifun <-link$linkinv
  4832.     fit$fitted.values <- ifun(fit$fitted.values)
  4833.     fit$family <- list(name=dist, link=link, "")
  4834.     fit$linear.predictors <- eta
  4835.     fit$iter <- sfit$iter
  4836.     fit$parms <- sfit$parms
  4837.     fit$df.residual <- fit$df.residual - sum(!sfit$fixed)
  4838.  
  4839.     # If singular.ok=T, there may be NA coefs.  The var matrix should
  4840.     #   be an inversion of the "non NA" portion.
  4841.     var <- 0*sfit$imat
  4842.     good <- c(!is.na(fit$coef), rep(T, ncol(var)-nvar))
  4843.     var[good,good] <- solve(qr(sfit$imat[good,good], tol=1e-12))
  4844.     fit$var <- var
  4845.     fit$fixed <- sfit$fixed
  4846.     dev <- sd$deviance(Y, fit$parms, sfit$deriv[,1])
  4847.     fit$dresiduals <- sign(fit$residuals)*sqrt(dev)
  4848.     fit$deviance <- sum(dev)
  4849.     fit$null.deviance <- fit$deviance +2*(sfit$loglik[2]- sfit$ndev[2])
  4850.     fit$loglik <- c(sfit$ndev[2], sfit$loglik[2])
  4851.     }
  4852.  
  4853.     na.action <- attr(m, "na.action")
  4854.     if (length(na.action)) fit$na.action <- na.action
  4855.     attr(fit, "class") <-  c("survreg", "glm", "lm")
  4856.     fit$terms <- Terms
  4857.     fit$formula <- as.vector(attr(Terms, "formula"))
  4858.     fit$call <- call
  4859.     if (model) fit$model <- m
  4860.     if (x)     fit$x <- X
  4861.     if (y)     fit$y <- Y
  4862.     fit
  4863.     }
  4864. # @(#)survsum.s    1.2 09/25/92
  4865. # written by Mark Dietrich
  4866. survsum <- function    
  4867.         (formula,data=sys.parent(),sptms=NULL,xlim,tlines=T,log=F,
  4868.         xscale=1,yscale=100,mark.time=F,mark=3,cex=1,xlab="Time",
  4869.         ylab="Survival (%)",lgd="bl",ttl="K-M Survival",...) {
  4870. #
  4871.     ltms <- length (sptms)            ##number of specified times
  4872. #
  4873. #------------------------------------------------------------------------------
  4874. #
  4875.     if (ltms >4){
  4876.             stop("Maximum number of specified times is four.")}
  4877.     if (ltms > 0){                        ##warnings
  4878.         if( any (sptms < 0))
  4879.             stop ("specified times must be positive")}
  4880. #
  4881. #------------------------------------------------------------------------------
  4882. #################
  4883. #total statistics#
  4884. ##################
  4885. #
  4886.     fit <- survfit (formula,data)            ##survfit object
  4887. #
  4888.     n.pts <- summary (fit,times=0,print.it=F)$n.risk
  4889.                           ##number of points in each group
  4890.     strat <- fit$strata              ##
  4891.     gp.name <- names(strat)          ## the group names
  4892.     n <- length (n.pts)              ##the number of groups
  4893. #
  4894.     if (n > 6) {                    ##too many groups
  4895.         stop("Maximum number of groups is 6")}
  4896. #
  4897.     code <- fit$n.event                ##coded events by time
  4898.     stemp <- rep (1:n,strat)
  4899.         events <- 1:n             ##number of events in each group 
  4900.                 for (i in (1:n))
  4901.                         events[i] <- sum (code [stemp ==i])
  4902. #
  4903. #------------------------------------------------------------------------------
  4904. ###############
  4905. #survival plot#
  4906. ###############
  4907. #
  4908.     par (fig = c(0,1,.10,.75))
  4909.     par (err=-1)                   ##supress out-of-bounds msgs
  4910. #
  4911.     frame ()
  4912.     if (missing(xlim)){        ##conditional: no xlim specified
  4913. #
  4914.         if (log) {            ##conditional: log=True
  4915. #
  4916.     ends <- plot (fit,lty=c(1,2,7,8,3,5),xaxs="i",xscale=xscale,log=T,
  4917.     ,xlab=xlab,ylab=ylab,mark.time=mark.time,mark=mark,cex=cex,las=1,...)
  4918.                                          ##Plot
  4919.         } else {            ##conditional: log=False
  4920. #
  4921.     ends <- plot (fit,lty=c(1,2,7,8,3,5),xaxs="i",yaxs="i",
  4922.     xscale=xscale,yscale=yscale,xlab=xlab,ylab=ylab,mark.time=mark.time,
  4923.     mark=mark,cex=cex,ylim=c(0,(yscale+(yscale/10))),las=1,...)    ##Plot
  4924. #
  4925.         }
  4926.     xlim <- c(0,max(ends$x))           ##supply xlim value needed below
  4927. #
  4928.     } else {            ##conditional: xlim is specified
  4929. #
  4930.         if (log) {            ##conditional: log=True
  4931. #
  4932.     ends <- plot (fit,lty=c(1,2,7,8,3,5),xaxs="i",xlim=xlim,
  4933.     log=T,xscale=xscale,xlab=xlab,ylab=ylab,mark.time=mark.time,mark=mark,
  4934.     cex=cex,las=1,...)                             ##Plot
  4935. #
  4936.         } else {            ##conditional: log=False
  4937. #
  4938.     ends <- plot (fit,lty=c(1,2,7,8,3,5),xaxs="i",yaxs="i",
  4939.     xlim=xlim,xlab=xlab,ylab=ylab,mark.time=mark.time,mark=mark,cex=cex,
  4940.     xscale=xscale,yscale=yscale,ylim=c(0,(yscale+(yscale/10))),las=1,...)
  4941.                                     ##Plot
  4942.             }}
  4943. #
  4944. #
  4945.     small <- xlim[1]            ##minimum x value on plot 
  4946.     big <- xlim[2]                ##maximum x value on plot
  4947. #    
  4948.     par (err=0)                ##error msgs resumed
  4949. #
  4950. #------------------------------------------------------------------------------
  4951. #################
  4952. #specified times#
  4953. #################
  4954. #
  4955.     vec <- rep(NA,4)        ##vector of NA's:used if ltms=0
  4956.     vec[1:ltms] <- sptms        ##NA's replaced with specified times
  4957.     t1 <- vec[1]            ##variables assigned timepoints
  4958.     t2 <- vec[2]
  4959.     t3 <- vec[3]
  4960.     t4 <- vec[4]
  4961. #
  4962. #-----------------------------------------------------------------------------
  4963. ################
  4964. #vertical lines#
  4965. ################
  4966. #
  4967.         if (tlines){                ##conditional: tlines=True
  4968.         lin.ok <- vec [!is.na(vec)]    ##times that are not NA
  4969. #
  4970.     if (ltms != 0){
  4971.     if (any (lin.ok < small) | any (lin.ok > big))
  4972.                         ##conditional:    times <
  4973.                         ##             xmin or > xmax
  4974.         stop ("a specified (sptms) time point falls outside the plot region.")
  4975. #
  4976.         abline (v=c(lin.ok),lty=4)         ##vertical lines
  4977.                 axis (3,at=c(lin.ok),labels=c(lin.ok))}} ##axis labels at times
  4978. #
  4979. #------------------------------------------------------------------------------
  4980. ########
  4981. #legend#
  4982. ########
  4983. #
  4984.     par (fig=c(0,1,0,1))
  4985.     a <- 1:100
  4986.     b <- 1:100
  4987. #
  4988.     plot (a,b,type="n",xlab="",ylab="",bty="n",axes=F)
  4989. #
  4990.     if (lgd=="bl") {        ##conditional: legend at bottom-right
  4991. #
  4992.     if (n == 6) {
  4993.         legend (0,30,legend=names (fit$strata),
  4994.                             lty=c(1,2,7,8,3,5))
  4995.             } else {
  4996.     if (n == 5) {
  4997.         legend (0,28,legend=names (fit$strata),
  4998.                             lty=c(1,2,7,8,3,5))
  4999.             } else {
  5000.     if (n == 4) {
  5001.         legend (0,26,legend=names (fit$strata),
  5002.                             lty=c(1,2,7,8,3,5))
  5003.             } else {
  5004.     if (n == 3) {
  5005.         legend (0,24,legend=names (fit$strata),
  5006.                             lty=c(1,2,7,8,3,5))
  5007.             } else {
  5008.     if (n == 2) {
  5009.         legend (0,22,legend=names (fit$strata),
  5010.                             lty=c(1,2,7,8,3,5))
  5011.             } else {
  5012.         legend (0,20,legend=names (fit$strata),
  5013.                             lty=c(1,2,7,8,3,5))
  5014. }}}}}
  5015.         } else {
  5016. #
  5017.     if (lgd =="tr") {        ##conditional: legend at top-right
  5018. #
  5019.         legend (75,69,legend=names (fit$strata),
  5020.         lty=c(1,2,7,8,3,5))
  5021. #
  5022.         } else {
  5023. #
  5024.     if (lgd == "n")             ##conditional: no legend 
  5025.         {    }}}
  5026. #
  5027.     par (fig = c(0,1,0,1))
  5028. #
  5029.     if (lgd == "under"){        ##conditional: legend under plot
  5030.         legend (75,4,legend=names (fit$strata),
  5031.         lty=c(1,2,7,8,3,5))}
  5032. #
  5033. #------------------------------------------------------------------------------
  5034. #####################
  5035. #test for difference#
  5036. #####################
  5037. #
  5038.     sdif <- survdiff(eval(fit$call$formula), eval (fit$call$data))
  5039.                     ##survdiff function
  5040.         chisq <- round(sdif$chisq,2)    ##chisquare statistic
  5041.         df <- length (sdif$n) - 1    ##degrees of freedom
  5042.         p <- round(1 - pchisq(sdif$chisq, df),4)    ##p-value
  5043.                 if (p < .0001) (p <- ".0001")        
  5044. #
  5045.     text (0,-5,paste("LOGRANK TEST (all curves equal): Chi-Square = "
  5046.     ,chisq,"   ","df = ",df,"   ","p = ",p),adj=0)
  5047. #
  5048.     mtext(date(),side=1,outer=T,adj=1)        ##date
  5049. #
  5050. #------------------------------------------------------------------------------
  5051. #############################
  5052. #printing on graphics device#
  5053. #############################
  5054. #
  5055.     ysfull <- c(80,72,64,56,48,40)          ##y-values
  5056.         ys <- ysfull[1:n]
  5057. #
  5058.     par (fig = c(0,1,.5,1))
  5059. #
  5060. # jds -- switch ttl and "K-M Survival"
  5061.     if (!missing(ttl)) 
  5062.         mtext("K-M Survival",side=3,outer=T,adj=1)
  5063.     plot (a,b,type="n",xaxt="n",yaxt="n",xlab="",ylab="",bty="n",main=ttl)
  5064. #
  5065.     x1 <- c(rep(-5,n+1),-5,20)
  5066.     y1 <- c(90,ys,90,105)
  5067.     labs1 <- c("Group",gp.name,"_________________________________________",
  5068.             "Totals")
  5069.     text (x1,y1,labs1,adj=0)
  5070. #
  5071.     x2 <- c(20,rep(18,n),32,rep(30,n))
  5072.     y2 <- c(90,ys,90,ys)
  5073.     labs2 <- c("No.Pts.",n.pts,"No.Events",events)
  5074.     text (x2,y2,labs2,adj=1)
  5075. #
  5076. #
  5077. ##########################
  5078. #specific time statistics#
  5079. ##########################
  5080. #
  5081.     gt1 <- gt2 <- gt3 <- gt4 <- NA        ##return value dummy variables
  5082.  
  5083.     if (!is.na (t1)) {            ##conditional: t1 is not NA
  5084. #
  5085.     text (38,105,"Estimated survival % (SE,n) at time (t)",adj=0)
  5086. #
  5087. #################
  5088. #define function#
  5089. #################
  5090. #
  5091.     group <- function (ti,x,current.fit,m,gpn,scale,endsx) {
  5092. #
  5093.                     if (ti > max(endsx)){    ##conditional: time > xmax
  5094. #
  5095.             text (x,90,c(paste("t=", ti),"___________"),adj=0)
  5096.                 text(x,80,"no data",adj=0)
  5097.                     } else {        ##conditional: time < xmax
  5098. #
  5099.             mat <- summary.survfit (current.fit,times=ti,print.it=F,
  5100.                     scale=scale)
  5101. #    
  5102.         gps <- mat$strata    ##group names used at time
  5103.  
  5104.             bigm <- matrix(rep(NA,m*3),ncol=3)
  5105. #
  5106.             dimnames (bigm) <- list (gpn,c("percs","se","n"))
  5107. #
  5108.             percs <- format (round (mat$surv*100,1))  ##survival percentage
  5109.             sters <- format(round (mat$std.err*100,1))     ##standard error
  5110.             nrisk <- format(mat$n.risk)               ##no. at risk
  5111. #
  5112.         bigm [as.character(gps),] <- c(percs,sters,nrisk)
  5113.  
  5114.             ysfull <- c(80,72,64,56,48,40)          ##y-values
  5115.             ys <- ysfull[1:m]
  5116. #
  5117.             text (x,90,c(paste("t=", ti),"___________"),adj=0)
  5118.             text (rep(x,m),ys,paste(bigm[1:m,1],"(",bigm[1:m,2],",",
  5119.         bigm[1:m,3],")"),adj=0)
  5120.         list (bigm = bigm)
  5121.         }}
  5122. #
  5123.         f1 <- group (t1,35,fit,n,gp.name,xscale,ends$x)
  5124.         gt1 <- f1$bigm
  5125.         gt2 <- gt3 <- gt4 <- NA
  5126. #
  5127.     if (!is.na (t2)) {            ##conditional: t2 is not NA
  5128.         f2 <- group (t2,52,fit,n,gp.name,xscale,ends$x)
  5129.         gt2 <- f2$bigm
  5130.         gt3 <- gt4 <- NA
  5131. #
  5132.     if (!is.na (t3)) {            ##conditional: t3 is not NA
  5133.         f3 <- group (t3,69,fit,n,gp.name,xscale,ends$x)
  5134.         gt3 <- f3$bigm
  5135.         gt4 <- NA
  5136. #
  5137.     if (!is.na (t4)) {            ##conditional: t4 is not NA
  5138.         f4 <- group (t4,86,fit,n,gp.name,xscale,ends$x)
  5139.         gt4 <- f4$bigm
  5140. }}}}
  5141. invisible(list(no.pts=n.pts,no.events=events,chisq=chisq,p=p,t1=gt1,
  5142.         t2=gt2,t3=gt3,t4=gt4 ))            ##return values
  5143. }
  5144.  
  5145.  
  5146.  
  5147.  
  5148.  
  5149.  
  5150.  
  5151.  
  5152.  
  5153.  
  5154.  
  5155.  
  5156.  
  5157.  
  5158.  
  5159.  
  5160. #SCCS @(#)tcut.s    4.2 10/16/94
  5161. tcut <-  function (x, breaks, labels, scale=1){
  5162.     if(length(breaks) == 1) {
  5163.     if(breaks < 1)
  5164.         stop("Must specify at least one interval")
  5165.     if(missing(labels))
  5166.         labels <- paste("Range", seq(length = breaks))
  5167.     else if(length(labels) != breaks)
  5168.         stop("Number of labels must equal number of intervals")
  5169.     r <- range(x[!is.na(x)])
  5170.     r[is.na(r)] <- 1
  5171.     if((d <- diff(r)) == 0) {
  5172.         r[2] <- r[1] + 1
  5173.         d <- 1
  5174.         }
  5175.     breaks <- seq(r[1] - 0.01 * d, r[2] + 0.01 * d, length = breaks +1)
  5176.     }
  5177.     else {
  5178.     if(is.na(adb <- all(diff(breaks) >= 0)) || !adb)
  5179.        stop("breaks must be given in ascending order and contain no NA's")
  5180.     if(missing(labels))
  5181.         labels <- paste(format(breaks[ - length(breaks)]),
  5182.             "+ thru ", format(breaks[-1]), sep = "")
  5183.     else if(length(labels) != length(breaks) - 1)
  5184.        stop("Number of labels must be 1 less than number of break points")
  5185.     }
  5186.  
  5187.     structure(x*scale, cutpoints=breaks*scale, labels=labels, class='tcut')
  5188.     }
  5189.  
  5190. "[.tcut" <- function(x,i) {
  5191.     atts <- attributes(x)
  5192.     class(x) <- NULL
  5193.     x <- x[i]
  5194.     attributes(x) <- atts
  5195.     x
  5196.     }
  5197. #SCCS @(#)untangle.specials.s    4.1 07/10/92
  5198. untangle.specials <- function(tt, special, order=1) {
  5199.     #
  5200.     # There was a change in the specials, so action depends on your release
  5201.     #   of S
  5202.     #
  5203.     spc <- attr(tt, 'specials')[[special]]
  5204.     if (length(spc)==0)
  5205.     return(vars=character(0), terms=numeric(0))
  5206.  
  5207. ###<TSL>    facs <- attr(tt, 'factor')
  5208.     facs <- attr(tt, 'factors')
  5209. ###</TSL>
  5210.     fname <- dimnames(facs)
  5211.  
  5212.     if ((attr(terms(y~ zed(x), specials='zed'), 'specials'))$zed ==1) {
  5213.     # old style
  5214.     if (any(order>1))
  5215.        warning("Can't select specials based on the order of the terms")
  5216.     list(vars=(fname[[2]])[spc],  terms=spc)
  5217.     }
  5218.     else {
  5219.     ff <- apply(facs[spc,,drop=F], 2, sum)
  5220.     list(vars= (fname[[1]])[spc],
  5221.          terms= seq(ff)[ff & match(attr(tt, 'order'), order, nomatch=0)])
  5222.     }
  5223.     }
  5224.