The R Project SVN R-packages

Rev

Rev 104 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

S-PLUS : Copyright (c) 1988, 1996 MathSoft, Inc.
S : Copyright AT&T.
Version 3.4 Release 1 for Sun SPARC, SunOS 5.3 : 1996 
Mayo local startup...
    loading survival
    loading date
    loading slocal.misc
    set missing value action to 'na.omit'
    set contrasts to ('contr.treatment', 'contr.poly')
    stop automatic character -> factor conversion in data frames

Working data will be in .Data 
> #
> # Set up for the test
> #
> dyn.load("../loadmod.o")
> attach("../.Data")
> options(na.action="na.omit", contrasts="contr.treatment")
> #
> # Compute some answers "by hand"
> #     For test1 and test2 data
> byhand1 <- function(coef, newx) {
+     s <- exp(coef);+     loglik <- 2*coef - (log(3*s+3) + 2*log(s+3));+     u <- (6 + 3*s - s^2) / ((s+1)*(s+3));+     imat <- s/(s+1)^2 + 6*s/(s+3)^2;+ 
+     x <- c(1,1,1,0,0,0);+     status <- c(1,0,1,1,0,1);+     xbar <- c(s/(s+1), s/(s+3), 0, 0);+     haz <- c(1/(3*s+3), 2/(s+3), 0, 1 );+     ties <- c(1,1,2,2,3,4);+     wt <- c(s,s,s,1,1,1);+     mart <- c(1,0,1,1,0,1) -  wt* (cumsum(haz))[ties];+ 
+     score <- rep(6,0);+     for (i in 1:6) {
+   j <- ties[i];+  score[i] <-  -wt[i]*(cumsum((x[i]-xbar) * haz))[j];+    score[i] <- score[i] + wt[i]* ((x[i]-xbar)*status[i])[j];+  };+ 
+     scho <- c(1/(s+1), (3-s)/(3+s), 0);+ 
+     surv  <- exp(-cumsum(haz)* exp(coef*newx));+     varhaz.g <- cumsum(c(1/(3*s+3)^2, 2/(s+3)^2, 0, 1 ));+ 
+     varhaz.d <- cumsum((newx-xbar) * haz);+ 
+     varhaz <- (varhaz.g + varhaz.d0^2/ imat) * exp(2*coef*newx);+ 
+     names(xbar) <- names(haz) <- 1:4;+     names(surv) <- names(varhaz) <- 1:4;+     list(loglik=loglik, u=u, imat=imat, xbar=xbar, haz=haz,
+        mart=mart,  score=score,
+       scho=scho, surv=surv, var=varhaz,
+       varhaz.g=varhaz.g, varhaz.d=varhaz.d);+     }
> > > byhand2 <- function(coef, newx) {
+     s <- exp(coef);+ 
+     loglik <- 4*coef - log(s+1) - log(s+2) - 3*log(3*s+2) - 2*log(3*s+1);+     u <- 1/(s+1) +  1/(3*s+1) + 4/(3*s+2) -
+        ( s/(s+2) +3*s/(3*s+2) + 3*s/(3*s+1));+     imat <- s/(s+1)^2 + 2*s/(s+2)^2 + 6*s/(3*s+2)^2 +
+       3*s/(3*s+1)^2 + 3*s/(3*s+1)^2 + 12*s/(3*s+2)^2;+ 
+     hazard <-c( 1/(s+1), 1/(s+2), 1/(3*s+2), 1/(3*s+1), 1/(3*s+1), 2/(3*s+2) );+     xbar <- c(s/(s+1), s/(s+2), 3*s/(3*s+2), 3*s/(3*s+1), 3*s/(3*s+1),
+       3*s/(3*s+2));+ 
+     var.g <- cumsum(hazard*hazard /c(1,1,1,1,1,2));+     var.d <- cumsum( (xbar-newx)*hazard);+ 
+     surv <- exp(-cumsum(hazard) * exp(coef*newx));+     varhaz <- (var.g + var.d^2/imat)* exp(2*coef*newx);+ 
+     list(loglik=loglik, u=u, imat=imat, hazard=hazard,
+       xbar=xbar, surv=surv, varhaz=varhaz, var.g=var.g, var.d=var.d);+     }
> > byhand3 <- function(coef) {
+     #Hard coded -- what is found in the Agreg.3 comments file
+     s <- as.vector(exp(coef))  #kill the names attr;+ 
+     imat <- s/(s+1)^2 + 2*s/(s+2)^2 + 6*s/(3*s+2)^2 +
+       3*s/(3*s+1)^2 + 3*s/(3*s+1)^2 + 12*s/(3*s+2)^2;+ 
+     hazard <-c( 1/(s+1), 1/(s+2), 1/(3*s+2), 1/(3*s+1), 1/(3*s+1), 2/(3*s+2) );+     xbar <- c(s/(s+1), s/(s+2), 3*s/(3*s+2), 3*s/(3*s+1), 3*s/(3*s+1),
+       3*s/(3*s+2));+ 
+ 
+     newx <- c(0,0,1,1,1,0,0, 2,2,2,2);+     wt <- exp(coef*newx);+     indx <- c(1,2,4,5,6,1,2,3,4,5,6);+ 
+     var.g <- hazard*hazard /c(1,1,1,1,1,2);+     surv <- exp(-cumsum(hazard[indx]*wt));+     var1 <- cumsum(var.g[indx]*wt*wt);+     d    <- cumsum( (xbar[indx] - newx)* hazard[indx] * wt);+     var2 <- d^2/imat;+     names(surv) <- names(var1) <-names(var2) <- NULL;+     list(time= c(2,3,7,8,9,12,13,16,17,18,19),
+    surv=surv, std= sqrt(var1 + var2), var.g=var1, var.d=var2, d=d,
+       hazard=hazard, wt=wt);+     }
> > # Create the simplest test data set
> #
> test1 <- data.frame(time=  c(4, 3,1,1,2,2,3),
+           status=c(1,NA,1,0,1,1,0),
+           x=     c(0, 2,1,1,1,0,0))
> #
> #   Do the test on the simple data set
> #
> 
> fit <-coxph(Surv(time, status) ~x, test1, method="breslow")
> fit
Call:
coxph(formula = Surv(time, status) ~ x, data = test1, method = "breslow")


  coef exp(coef) se(coef)    z    p 
x 1.48      4.37     1.26 1.17 0.24

Likelihood ratio test=1.48  on 1 df, p=0.224  n=6 (1 observations deleted due to missing)
> fit0 <-coxph(Surv(time, status) ~x, test1, iter=0)
> fit0$coef
 x 
 0
> coxph(Surv(time, status) ~x, test1, iter=1, method="breslow")$coef
   x 
 1.6
> coxph(Surv(time, status) ~x, test1, iter=2, method="breslow")$coef
        x 
 1.472724
Warning messages:
  Ran out of iterations and did not converge in: fitter(X, Y, strats, offset,
    init = init, iter.max = iter.max, eps = eps,  ....
> coxph(Surv(time, status) ~x, test1, iter=3, method="breslow")$coef
        x 
 1.475284
> > coxph(Surv(time, status) ~ x, test1, method="efron")
Call:
coxph(formula = Surv(time, status) ~ x, data = test1, method = "efron")


  coef exp(coef) se(coef)    z    p 
x 1.68      5.35     1.28 1.31 0.19

Likelihood ratio test=1.84  on 1 df, p=0.175  n=6 (1 observations deleted due to missing)
> coxph(Surv(time, status) ~ x, test1, method="exact")
Call:
coxph(formula = Surv(time, status) ~ x, data = test1, method = "exact")


  coef exp(coef) se(coef)      z    p 
x 10.2     26980      116 0.0878 0.93

Likelihood ratio test=2.77  on 1 df, p=0.0959  n=6 (1 observations deleted due to missing)
Warning messages:
  Loglik converged before variable  1 ; beta may be infinite.  in: fitter(X, Y,
    strats, offset, init = init, iter.max = iter.max, eps = eps,  ....
> > resid(fit0)
     1  2         3          4         5         6     7 
 -0.75 NA 0.8333333 -0.1666667 0.4166667 0.4166667 -0.75
> resid(coxph(Surv(time, status) ~1, test1))
     1  2         3          4         5         6     7 
 -0.75 NA 0.8333333 -0.1666667 0.4166667 0.4166667 -0.75
> resid(fit0, "scor")
         1  2         3           4         5           6         7 
 0.2013889 NA 0.4166667 -0.08333333 0.3819444 -0.03472222 0.2013889
> resid(fit0, "scho")
   1         2          2 4 
 0.5 0.7916667 -0.2083333 0
> > resid(fit)
          1  2         3          4          5         6          7 
 -0.3333335 NA 0.7287136 -0.2712864 -0.4574266 0.6666665 -0.3333335
> resid(fit, "scor")
         1  2         3           4          5          6         7 
 0.2113894 NA 0.1356433 -0.05049747 -0.1262435 -0.3816807 0.2113894
> resid(fit, "scho")
         1         2          2 4 
 0.1861408 0.4069299 -0.5930701 0
> > predict(fit, type="lp")
         1  2        3        4        5         6         7 
 -0.737642 NA 0.737642 0.737642 0.737642 -0.737642 -0.737642
> predict(fit, type="risk")
         1  2        3        4        5         6         7 
 0.4782403 NA 2.090999 2.090999 2.090999 0.4782403 0.4782403
> predict(fit, type="expected")
        1  2         3         4        5         6         7 
 1.333334 NA 0.2712864 0.2712864 1.457427 0.3333335 0.3333335
> predict(fit, type="terms")
         1  2        3        4        5         6         7 
 -0.737642 NA 0.737642 0.737642 0.737642 -0.737642 -0.737642
> predict(fit, type="lp", se.fit=T)
$fit:
         1  2        3        4        5         6         7 
 -0.737642 NA 0.737642 0.737642 0.737642 -0.737642 -0.737642

$se.fit:
[1] 0.6278671        NA 0.6278671 0.6278671 0.6278671 0.6278671 0.6278671

> predict(fit, type="risk", se.fit=T)
$fit:
         1  2        3        4        5         6         7 
 0.4782403 NA 2.090999 2.090999 2.090999 0.4782403 0.4782403

$se.fit:
        1  2         3         4         5        6        7 
 0.434201 NA 0.9079139 0.9079139 0.9079139 0.434201 0.434201

> predict(fit, type="expected", se.fit=T)
$fit:
        1  2         3         4        5         6         7 
 1.333334 NA 0.2712864 0.2712864 1.457427 0.3333335 0.3333335

$se.fit:
        1  2         3         4        5         6         7 
 1.154701 NA 0.5208516 0.5208516 1.207239 0.5773504 0.5773504

> predict(fit, type="terms", se.fit=T)
$fit:
         1  2        3        4        5         6         7 
 -0.737642 NA 0.737642 0.737642 0.737642 -0.737642 -0.737642

$se.fit:
         1  2         3         4         5         6         7 
 0.6278671 NA 0.6278671 0.6278671 0.6278671 0.6278671 0.6278671

> > summary(survfit(fit))
Call: survfit.coxph(object = fit)

 time n.risk n.event survival std.err lower 95% CI upper 95% CI 
    1      6       1   0.8783   0.122      0.66827            1
    2      4       2   0.4981   0.218      0.21125            1
    4      1       1   0.0615   0.150      0.00051            1
> summary(survfit(fit, list(x=2)))
Call: survfit.coxph(object = fit, newdata = list(x = 2))

 time n.risk n.event survival  std.err lower 95% CI upper 95% CI 
    1      6       1 3.05e-01 6.50e-01     4.72e-03            1
    2      4       2 1.71e-03 1.98e-02     2.33e-13            1
    4      1       1 8.52e-12 5.29e-10     1.22e-64            1
> #
> # Create the simple data for agreg
> #
> 
> test2 <- data.frame(start=c(1, 2, 5, 2, 1, 7, 3, 4, 8, 8),
+           stop =c(2, 3, 6, 7, 8, 9, 9, 9,14,17),
+           event=c(1, 1, 1, 1, 1, 1, 1, 0, 0, 0),
+           x    =c(1, 0, 0, 1, 0, 1, 1, 1, 0, 0) )
> #
> #   Do the test on the simple agreg data set
> #
> fit <-coxph(Surv(start, stop, event)~ x, test2, method="breslow")
> fit
Call:
coxph(formula = Surv(start, stop, event) ~ x, data = test2, method = "breslow")


     coef exp(coef) se(coef)      z    p 
x -0.0845     0.919    0.794 -0.106 0.92

Likelihood ratio test=0.01  on 1 df, p=0.915  n= 10 
> fit0 <-coxph(Surv(start, stop, event)~ x, test2, iter=0)
> fit0$coef
 x 
 0
> coxph(Surv(start, stop, event)~ x, test2, iter=1, method="breslow")$coef
           x 
 -0.08507621
> coxph(Surv(start, stop, event)~ x, test2, iter=2, method="breslow")$coef
          x 
 -0.0845261
> coxph(Surv(start, stop, event)~ x, test2, iter=3, method="breslow")$coef
          x 
 -0.0845261
> > coxph(Surv(start, stop, event) ~ x, test2, method="efron")
Call:
coxph(formula = Surv(start, stop, event) ~ x, data = test2, method = "efron")


     coef exp(coef) se(coef)       z    p 
x -0.0211     0.979    0.795 -0.0266 0.98

Likelihood ratio test=0  on 1 df, p=0.979  n= 10 
> coxph(Surv(start, stop, event) ~ x, test2, method="exact")
Call:
coxph(formula = Surv(start, stop, event) ~ x, data = test2, method = "exact")


     coef exp(coef) se(coef)      z    p 
x -0.0916     0.912    0.827 -0.111 0.91

Likelihood ratio test=0.01  on 1 df, p=0.912  n= 10 
> > resid(fit0)
   1         2   3         4          5     6      7     8     9    10 
 0.5 0.6666667 0.8 0.2166667 -0.5333333 0.425 -0.025 -1.15 -0.45 -0.45
> resid(fit0, "scor")
    1          2     3          4         5     6      7     8     9    10 
 0.25 -0.2222222 -0.48 -0.1147222 0.1061111 0.245 0.1025 -0.41 0.245 0.245
> resid(fit0, "scho")
   2          3    6    7     8    9    9 
 0.5 -0.3333333 -0.6 0.25 -0.75 0.45 0.45
> > resid(fit)
        1         2         3         4          5         6           7 
 0.521119 0.6574108 0.7897765 0.2473877 -0.6062935 0.3690249 -0.06876579
         8          9         10 
 -1.068766 -0.4204469 -0.4204469
> resid(fit, "scor")
        1          2          3           4         5         6          7 
 0.271565 -0.2069671 -0.4577174 -0.09586133 0.1360823 0.1928898 0.04655652
          8         9        10 
 -0.3738904 0.2436713 0.2436713
> resid(fit, "scho")
        2          3          6         7          8         9         9 
 0.521119 -0.3148216 -0.5795531 0.2661809 -0.7338191 0.4204469 0.4204469
> > resid(coxph(Surv(start, stop, event)~ x, test2, iter=0, init=log(2)), "score")
         1      2        3          4          5         6          7 
 0.1111111 -0.375 -0.65625 -0.2104592 -0.1712727 0.1327948 0.02947846
          8         9        10 
 -0.3177438 0.2048611 0.2048611
> > sfit <-survfit(fit)
> sfit
Call: survfit.coxph(object = fit)

 n events mean se(mean) median 0.95LCL 0.95UCL 
 2      7 4.77     2.16      3       2      NA
> summary(sfit)
Call: survfit.coxph(object = fit)

 time n.risk n.event survival std.err lower 95% CI upper 95% CI 
    2      2       1    0.607   0.303       0.2279        1.000
    3      3       1    0.437   0.262       0.1347        1.000
    6      5       1    0.357   0.226       0.1034        1.000
    7      4       1    0.277   0.188       0.0729        1.000
    8      4       1    0.214   0.156       0.0514        0.894
    9      5       2    0.143   0.112       0.0308        0.667
> > # make a doubled data set
> temp <- rbind(test2, test2)
> temp <- data.frame(temp, x2=c(test2$x, test2$x^2), 
+                ss=c(rep(0, nrow(test2)), rep(1, nrow(test2))))
> fitx <- coxph(Surv(start, stop, event) ~ x2 * strata(ss), data=temp,
+         method="breslow")
> > sfit <- survfit(fitx, c(fitx$means[1], 0) )
> sfit
Call: survfit.coxph(object = fitx, newdata = c(fitx$means[1], 0))

     n events mean se(mean) median 0.95LCL 0.95UCL 
ss=0 2      7 4.77     2.16      3       2      NA
ss=1 2      7 4.77     2.16      3       2      NA
> summary(sfit)
Call: survfit.coxph(object = fitx, newdata = c(fitx$means[1], 0))

                ss=0 
 time n.risk n.event survival std.err lower 95% CI upper 95% CI 
    2      2       1    0.607   0.303       0.2279        1.000
    3      3       1    0.437   0.262       0.1347        1.000
    6      5       1    0.357   0.226       0.1034        1.000
    7      4       1    0.277   0.188       0.0729        1.000
    8      4       1    0.214   0.156       0.0514        0.894
    9      5       2    0.143   0.112       0.0308        0.667

                ss=1 
 time n.risk n.event survival std.err lower 95% CI upper 95% CI 
    2      2       1    0.607   0.346      0.19854            1
    3      3       1    0.437   0.321      0.10358            1
    6      5       1    0.357   0.298      0.06946            1
    7      4       1    0.277   0.275      0.03950            1
    8      4       1    0.214   0.248      0.02218            1
    9      5       2    0.143   0.199      0.00946            1

> #
> # Even though everyone in strata 1 has x2==0, I won't get the same survival
> #  curve above if survfit is called without forcing predicted x2 to be
> #  zero-- otherwise I am asking for a different baseline than the
> #  simple model did.  In this particular case coef[2] is nearly zero, so
> #  the curves are the same, but the variances differ.
> #
> 
> # This mimics 'byhand3' and the documentation
> fit <- coxph(Surv(start, stop, event) ~x, test2, method="breslow")
> tdata <- data.frame( start=c(0,20, 6,0,5),
+            stop =c(5,23,10,5,15),
+            event=rep(0,5),
+            x=c(0,0,1,0,2) )
> > temp <- survfit(fit, tdata, individual=T)
> temp2 <- byhand3(fit$coef)
> all.equal(temp$surv, temp2$surv)
[1] T
> all.equal(temp2$std, temp$std.err)
[1] T
> > temp2
$time:
 [1]  2  3  7  8  9 12 13 16 17 18 19

$surv:
 [1] 0.59385568 0.42159583 0.33011489 0.25848416 0.17564514 0.10430786
 [7] 0.07405126 0.06200600 0.04952367 0.03955414 0.02773285

$std:
 [1] 0.5575022 0.6851479 0.7089453 0.7356099 0.7654270 0.9576269 1.0413781
 [8] 1.0108872 1.0307723 1.0978065 1.2970159

$var.g:
 [1] 0.2715650 0.3889323 0.4487646 0.5085969 0.5832373 0.8548022 0.9721696
 [8] 1.0036852 1.0542114 1.1047377 1.1677689

$var.d:
 [1] 0.039243716 0.080495343 0.053838816 0.032524984 0.002641259 0.062246981
 [7] 0.112298842 0.018207698 0.008280014 0.100441497 0.514481487

$d:
 [1]  0.24955399  0.35740846  0.29229891  0.22718937  0.06474183  0.31429582
 [7]  0.42215029  0.16998358 -0.11462913 -0.39924183 -0.90357526

$hazard:
[1] 0.5211190 0.3425892 0.2102235 0.2661809 0.2661809 0.4204469

$wt:
 [1] 1.0000000 1.0000000 0.9189477 0.9189477 0.9189477 1.0000000 1.0000000
 [8] 0.8444648 0.8444648 0.8444648 0.8444648

> #
> # Test out the survival curve and variance, in gory detail
> #
> xdata <- data.frame(rbind(test1,test1), ss = rep(1:2, rep(nrow(test1),2)))
> fit <- coxph(Surv(time, status)~x + strata(ss), xdata, method="breslow")
> sfit <- survfit(fit, list(x=0))    #type='aalen' is default
> > # From the hand worked notes
> bb <- as.vector(exp(fit$coef))
> realhaz <- cumsum(c(1/(3*bb+3), 2/(bb+3), 1))
> all.equal(sfit$surv, exp(-rep(realhaz,2)))
[1] T
> > realvar <- cumsum(c( (1/(3*bb+3))^2, 2/(bb+3)^2, 1))
> dd <- cumsum(c( (bb/(bb+1))*(1/(3*bb+3)),
+           (bb/(bb+3))*(2/(bb+3)),  0*1))
> realvar <- realvar + dd^2 * fit$var
> all.equal(sfit$std, sqrt(rep(realvar,2)))
[1] T
> summary(sfit)
Call: survfit.coxph(object = fit, newdata = list(x = 0))

                ss=1 
 time n.risk n.event survival std.err lower 95% CI upper 95% CI 
    1      6       1    0.940  0.0719       0.8089            1
    2      4       2    0.717  0.1974       0.4176            1
    4      1       1    0.264  0.2734       0.0345            1

                ss=2 
 time n.risk n.event survival std.err lower 95% CI upper 95% CI 
    1      6       1    0.940  0.0719       0.8089            1
    2      4       2    0.717  0.1974       0.4176            1
    4      1       1    0.264  0.2734       0.0345            1

> > # Get the Kalbfleisch-Prentice survival with Greenwood variance
> #  
> sfit <- survfit(fit, list(x=0), type="kalb")   
> > # second term is the solution to an equation, in the neighborhood of .6
> tfun <- function(alpha) (bb/(1-alpha^bb) + 1/(1-alpha) - (bb+3))^2
Warning messages:
  assigning "tfun" masks an object of the same name on database 2
> temp <- nlminb(0.6, tfun, lower=.1, upper=.9)
> > realkm <- cumprod(c((1- bb/(3*bb+3))^(1/bb), temp$par, 0))
> all.equal(sfit$surv, rep(realkm,2))
[1] T
> > realvar <- cumsum(c( 1/((3*bb+3)*(2*bb+3)), 2/((bb+3)*2), 1))
> dd <- cumsum(c( (bb/(bb+1))*(1/(3*bb+3)),
+           (bb/(bb+3))*(2/(bb+3)),  0*1))
> realvar <- realvar + dd^2 * fit$var
> all.equal(sfit$std, sqrt(rep(realvar,2)))
[1] T
> summary(sfit)
Call: survfit.coxph(object = fit, newdata = list(x = 0), type = "kalb")

                ss=1 
 time n.risk n.event survival std.err lower 95% CI upper 95% CI 
    1      6       1    0.930  0.0794        0.787            1
    2      4       2    0.556  0.2333        0.244            1
    4      1       1    0.000  0.0000        0.000            0

                ss=2 
 time n.risk n.event survival std.err lower 95% CI upper 95% CI 
    1      6       1    0.930  0.0794        0.787            1
    2      4       2    0.556  0.2333        0.244            1
    4      1       1    0.000  0.0000        0.000            0

> > > #
> # Repeat with the Efron approximation for Cox, Efron estimates
> #
> fit <- coxph(Surv(time, status)~x + strata(ss), xdata)
> sfit <- survfit(fit, list(x=0))    
> bb <- as.vector(exp(fit$coef))
> > realhaz <- cumsum(c(1/(3*bb+3), 1/(bb+3) + 2/(bb+5), 1))
> all.equal(sfit$surv, exp(-rep(realhaz,2)))
[1] T
> > realvar <- cumsum(c( (1/(3*bb+3))^2, 1/(bb+3)^2 + 4/(bb+5)^2, 1))
> dd <- cumsum(c( (bb/(bb+1))*(1/(3*bb+3)),
+           (bb/(bb+3))*(1/(bb+3))+ (bb/(bb+5))*(2/(bb+5)),  0*1))
> realvar <- realvar + dd^2 * fit$var
> all.equal(sfit$std, sqrt(rep(realvar,2)))
[1] T
> summary(sfit)
Call: survfit.coxph(object = fit, newdata = list(x = 0))

                ss=1 
 time n.risk n.event survival std.err lower 95% CI upper 95% CI 
    1      6       1    0.949  0.0626       0.8337            1
    2      4       2    0.694  0.2130       0.3801            1
    4      1       1    0.255  0.2670       0.0328            1

                ss=2 
 time n.risk n.event survival std.err lower 95% CI upper 95% CI 
    1      6       1    0.949  0.0626       0.8337            1
    2      4       2    0.694  0.2130       0.3801            1
    4      1       1    0.255  0.2670       0.0328            1

> > > rm(bb, sfit, realhaz, realvar, fit, realkm, xdata)
> #
> # The AML data, from Miller, "Survival Analysis", page 49.
> #
> aml <- list(time=   c( 9, 13, 13, 18, 23, 28, 31, 34, 45, 48, 161,
+              5,  5,  8,  8, 12, 16, 23, 27, 30, 33, 43, 45),
+       status= c( 1,1,0,1,1,0,1,1,0,1,0, 1,1,1,1,1,0,1,1,1,1,1,1),
+       x     = as.factor(c(rep("Maintained", 11),
+               rep("Nonmaintained", 12) )))
> > aml <- data.frame(aml)
> #
> # These results can be found in Miller
> #
> fit <- coxph(Surv(aml$time, aml$status) ~ aml$x, method="breslow")
> fit
Call:
coxph(formula = Surv(aml$time, aml$status) ~ aml$x, method = "breslow")


       coef exp(coef) se(coef)    z     p 
aml$x 0.904      2.47    0.512 1.77 0.078

Likelihood ratio test=3.3  on 1 df, p=0.0694  n= 23 
> resid(fit, type="mart")
         1         2          3         4         5          6         7 
 0.8622552 0.7920096 -0.2079904 0.7481884 0.6565293 -0.3979666 0.4542489
         8        9         10       11        12        13        14 
 0.2547496 -1.05401 -0.5540104 -1.55401 0.8784449 0.8784449 0.7400696
        15        16         17        18         19         20         21 
 0.7400696 0.5767732 -0.5137362 0.1516277 0.01702279 -0.1489718 -0.5644816
        22        23 
 -1.151851 -1.603405
> resid(fit, type="score")
          1          2        3          4          5         6          7 
 -0.5468557 -0.4925013 0.141064 -0.4799074 -0.4474163 0.2684542 -0.2359083
           8         9        10        11        12        13        14 
 -0.07265521 0.6408269 0.6408269 0.6408269 0.2377681 0.2377681 0.2325854
        15        16         17         18          19          20         21 
 0.2325854 0.2038792 -0.1653081 0.04492356 0.007079928 -0.03965181 -0.1811844
         22         23 
 -0.3950761 -0.4721168
> resid(fit, type="scho")
         5         5         8         8          9        12         13 
 0.2706694 0.2706694 0.3081233 0.3081233 -0.6423926 0.3360216 -0.6335653
         18         23        23        27        30        31        33 
 -0.6494303 -0.6791933 0.3208067 0.3269755 0.3360216 -0.597099 0.3505697
         34        43        45 48 
 -0.5525726 0.3778338 0.5484461  0
> > fit <- survfit(Surv(aml$time, aml$status) ~ aml$x)
> fit
Call: survfit(formula = Surv(aml$time, aml$status) ~ aml$x)

                     n events mean se(mean) median 0.95LCL 0.95UCL 
   aml$x=Maintained 11      7 52.6    19.83     31      18      NA
aml$x=Nonmaintained 12     11 22.7     4.18     23       8      NA
> summary(fit)
Call: survfit(formula = Surv(aml$time, aml$status) ~ aml$x)

                aml$x=Maintained 
 time n.risk n.event survival std.err lower 95% CI upper 95% CI 
    9     11       1    0.909  0.0867       0.7541        1.000
   13     10       1    0.818  0.1163       0.6192        1.000
   18      8       1    0.716  0.1397       0.4884        1.000
   23      7       1    0.614  0.1526       0.3769        0.999
   31      5       1    0.491  0.1642       0.2549        0.946
   34      4       1    0.368  0.1627       0.1549        0.875
   48      2       1    0.184  0.1535       0.0359        0.944

                aml$x=Nonmaintained 
 time n.risk n.event survival std.err lower 95% CI upper 95% CI 
    5     12       2   0.8333  0.1076       0.6470        1.000
    8     10       2   0.6667  0.1361       0.4468        0.995
   12      8       1   0.5833  0.1423       0.3616        0.941
   23      6       1   0.4861  0.1481       0.2675        0.883
   27      5       1   0.3889  0.1470       0.1854        0.816
   30      4       1   0.2917  0.1387       0.1148        0.741
   33      3       1   0.1944  0.1219       0.0569        0.664
   43      2       1   0.0972  0.0919       0.0153        0.620
   45      1       1   0.0000      NA           NA           NA

> survdiff(Surv(aml$time, aml$status)~ aml$x)
Call:
survdiff(formula = Surv(aml$time, aml$status) ~ aml$x)

                     N Observed Expected (O-E)^2/E (O-E)^2/V 
   aml$x=Maintained 11        7    10.69      1.27       3.4
aml$x=Nonmaintained 12       11     7.31      1.86       3.4

 Chisq= 3.4  on 1 degrees of freedom, p= 0.0653 
> > #
> # Test out the weighted K-M
> #
> #  First, equal case weights- shouldn't change the survival, but will
> #    halve the variance
> temp2 <-survfit(Surv(aml$time, aml$status), type="kaplan", weight=rep(2,23))
> temp  <-survfit(Surv(time, status)~1, aml)
> temp$surv/temp2$surv
 [1] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
> (temp$std.err/temp2$std.err)^2
 [1] 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
> > # Risk weights-- use a null Cox model
> tfit <- coxph(Surv(aml$time, aml$status) ~ offset(log(1:23)))
> sfit <- survfit(tfit, type="aalen")
> > # Now compute it by hand
> #  Ties are a challenge
> atime <- sort(aml$time)
> denom <- rev(cumsum(rev((1:23)[order(aml$time)])))
> denom <- denom[match(unique(atime), atime)]
> deaths <- tapply(aml$status, aml$time, sum)
> chaz <- cumsum(deaths/denom)
> all.equal(sfit$surv, as.vector(exp(-chaz[deaths>0])))
[1] T
> cvar <- cumsum(deaths/denom^2)
> all.equal(sfit$std^2, as.vector(cvar[deaths>0]))
[1] T
> summary(sfit)
Call: survfit.coxph.null(object = tfit, type = "aalen")

 time n.risk n.event survival std.err lower 95% CI upper 95% CI 
    5     23       2    0.993 0.00509        0.983        1.000
    8     21       2    0.985 0.00750        0.970        1.000
    9     19       1    0.980 0.00868        0.964        0.998
   12     18       1    0.976 0.00970        0.957        0.995
   13     17       1    0.971 0.01075        0.950        0.993
   18     14       1    0.966 0.01193        0.943        0.990
   23     13       2    0.955 0.01400        0.928        0.983
   27     11       1    0.949 0.01518        0.920        0.979
   30      9       1    0.942 0.01670        0.910        0.975
   31      8       1    0.934 0.01856        0.898        0.971
   33      7       1    0.925 0.02042        0.885        0.965
   34      6       1    0.913 0.02298        0.870        0.960
   43      5       1    0.901 0.02567        0.852        0.953
   45      4       1    0.885 0.03021        0.827        0.946
   48      2       1    0.843 0.04943        0.752        0.946
> > # And the Efron result
> summary(survfit(tfit))
Call: survfit.coxph.null(object = tfit)

 time n.risk n.event survival std.err lower 95% CI upper 95% CI 
    5     23       2    0.993 0.00521        0.982        1.000
    8     21       2    0.984 0.00771        0.970        1.000
    9     19       1    0.980 0.00885        0.963        0.998
   12     18       1    0.976 0.00986        0.957        0.995
   13     17       1    0.971 0.01089        0.950        0.992
   18     14       1    0.966 0.01205        0.942        0.990
   23     13       2    0.955 0.01424        0.927        0.983
   27     11       1    0.948 0.01540        0.919        0.979
   30      9       1    0.941 0.01689        0.909        0.975
   31      8       1    0.933 0.01873        0.897        0.970
   33      7       1    0.924 0.02057        0.884        0.965
   34      6       1    0.913 0.02310        0.869        0.959
   43      5       1    0.901 0.02577        0.852        0.953
   45      4       1    0.884 0.03029        0.826        0.945
   48      2       1    0.843 0.04944        0.751        0.945
> > # Lots of ties, so its a good test case
> x1 <- coxph(Surv(time, status)~x, aml, method="efron")
> x1
Call:
coxph(formula = Surv(time, status) ~ x, data = aml, method = "efron")


   coef exp(coef) se(coef)    z     p 
x 0.916       2.5    0.512 1.79 0.074

Likelihood ratio test=3.38  on 1 df, p=0.0658  n= 23 
> x2 <- coxph(Surv(rep(0,23),time, status) ~x, aml, method="efron")
> x1$coef - x2$coef
            x 
 2.220446e-16
> > rm(x1, x2, atime, denom, deaths, chaz,cvar, tfit, sfit, temp, temp2, fit)
> #
> # Trivial test of stratified residuals
> #   Make a second strata = replicate of the first, and I should get the
> #   exact same answers
> 
> temp <- as.matrix(test1)
> n    <- nrow(temp)
> ndead<- sum(test1$status[!is.na(test1$status)])
> temp <- data.frame(rbind(temp, temp)) #later releases of S have rbind.data.frame
> tstrat <- rep(1:2, c(n,n))
> > fit1 <- coxph(Surv(time, status) ~x, test1)
> fit2 <- coxph(Surv(time, status) ~x + strata(tstrat), temp)
> > all.equal(resid(fit1) , (resid(fit2))[1:n])
[1] T
> all.equal(resid(fit1, type="score") , (resid(fit2, type="score"))[1:n])
[1] T
> all.equal(resid(fit1, type="schoe") , (resid(fit2, type="schoe"))[1:ndead])
[1] T
> > > #AG model
> temp <- as.matrix(test2)
> n    <- nrow(temp)
> ndead<- sum(test2$event[!is.na(test2$event)])
> temp <- data.frame(rbind(temp, temp))
> tstrat <- rep(1:2, c(n,n))
> > fit1 <- coxph(Surv(start, stop, event) ~x, test2)
> fit2 <- coxph(Surv(start, stop, event) ~x + strata(tstrat), temp)
> > all.equal(resid(fit1) , (resid(fit2))[1:n])
[1] T
> all.equal(resid(fit1, type="score") , (resid(fit2, type="score"))[1:n])
[1] T
> all.equal(resid(fit1, type="schoe") , (resid(fit2, type="schoe"))[1:ndead])
[1] T
> #
> # A test to exercise the "infinity" check on 2 variables
> #
> test3 _ data.frame(futime=1:12, fustat=c(1,0,1,0,1,0,0,0,0,0,0,0),
+          x1=rep(0:1,6), x2=c(rep(0,6), rep(1,6)))
> coxph(Surv(futime, fustat) ~ x1 + x2, test3)
Call:
coxph(formula = Surv(futime, fustat) ~ x1 + x2, data = test3)


    coef exp(coef) se(coef)       z    p 
x1 -11.2  1.36e-05      156 -0.0716 0.94
x2 -11.9  6.51e-06      167 -0.0715 0.94

Likelihood ratio test=10.2  on 2 df, p=0.00625  n= 12 
Warning messages:
  Loglik converged before variable 1 ,2; beta may be infinite.  in: fitter(X,
    Y, strats, offset, init = init, iter.max = iter.max, eps = eps,  ....
> # Create a "counting process" version of the simplest test data set
> #
> test1b<- list(start= c(0, 3,  0,  0, 5,  0, 6,14,  0,  0, 10,20,30, 0),
+         stop = c(3,10, 10,  5,20,  6,14,20, 30,  10,20,30,40, 10),
+         status=c(0, 1,  0,  0, 1,  0, 0, 1,  0,   0, 0, 0, 1,  0),
+         x=     c(1, 1,  1,  1, 1,  0, 0, 0,  0,   0, 0, 0, 0,  NA),
+         id =   c(3, 3,  4,  5, 5,  6, 6, 6,  7,   1, 1, 1, 1,   2))
> #
> #  Check out the various residuals under an Efron approximation
> #
> fit0 <- coxph(Surv(time, status)~ x, test1, iter=0)
> fit  <- coxph(Surv(time, status) ~x, test1)
> fit0b <- coxph(Surv(start, stop, status) ~ x, test1b, iter=0)
> fitb  <- coxph(Surv(start, stop, status) ~x, test1b)
> fitc  <- coxph(Surv(time, status) ~ offset(fit$coef*x), test1)
> fitd  <- coxph(Surv(start, stop, status) ~ offset(fit$coef*x), test1b)
> > resid(fit0)
     1  2         3          4         5         6     7 
 -0.75 NA 0.8333333 -0.1666667 0.4166667 0.4166667 -0.75
> resid(fit0b, collapse=test1b$id)
     1  2         3          4         5         6     7 
 -0.75 NA 0.8333333 -0.1666667 0.4166667 0.4166667 -0.75
> resid(fit)
          1  2         3          4          5         6          7 
 -0.3655447 NA 0.7191709 -0.2808291 -0.4383383 0.7310859 -0.3655447
> resid(fitb, collapse=test1b$id)
          1  2         3          4          5         6          7 
 -0.3655447 NA 0.7191709 -0.2808291 -0.4383383 0.7310859 -0.3655447
> resid(fitc)
          1  2         3          4          5         6          7 
 -0.3655447 NA 0.7191709 -0.2808291 -0.4383383 0.7310859 -0.3655447
> resid(fitd, collapse=test1b$id)
          1  2         3          4          5         6          7 
 -0.3655447 NA 0.7191709 -0.2808291 -0.4383383 0.7310859 -0.3655447
> all.equal(resid(fitc), resid(fit))
[1] T
> > resid(fit0, type="score")
         1  2         3           4         5           6         7 
 0.2013889 NA 0.4166667 -0.08333333 0.3819444 -0.03472222 0.2013889
> resid(fit0b, type="score", collapse=test1b$id)
         1  2         3           4         5           6         7 
 0.2013889 NA 0.4166667 -0.08333333 0.3819444 -0.03472222 0.2013889
> resid(fit, type="score")
         1  2         3           4          5          6         7 
 0.2208587 NA 0.1132786 -0.04423418 -0.1029191 -0.4078391 0.2208587
> resid(fitb, type="score", collapse=test1b$id)
         1  2         3           4          5          6         7 
 0.2208587 NA 0.1132786 -0.04423418 -0.1029191 -0.4078391 0.2208587
> > resid(fit0, type="scho")
   1         2          2 4 
 0.5 0.7916667 -0.2083333 0
> resid(fit0b, type="scho", collapse=test1b$id)
  10        20         20 40 
 0.5 0.7916667 -0.2083333  0
> resid(fit, type="scho")
         1         2          2 4 
 0.1575128 0.4212454 -0.5787546 0
> resid(fitb, type="scho", collapse=test1b$id)
        10        20         20 40 
 0.1575128 0.4212454 -0.5787546  0
> > summary(survfit(fit0, list(x=0)))
Call: survfit.coxph(object = fit0, newdata = list(x = 0))

 time n.risk n.event survival std.err lower 95% CI upper 95% CI 
    1      6       1    0.846   0.169       0.5725            1
    2      4       2    0.472   0.246       0.1700            1
    4      1       1    0.174   0.196       0.0191            1
> summary(survfit(fit, list(x=0)))
Call: survfit.coxph(object = fit, newdata = list(x = 0))

 time n.risk n.event survival std.err lower 95% CI upper 95% CI 
    1      6       1    0.949  0.0732       0.8157            1
    2      4       2    0.694  0.2541       0.3385            1
    4      1       1    0.255  0.2718       0.0317            1
> summary(survfit(fitb,list(x=0)))
Call: survfit.coxph(object = fitb, newdata = list(x = 0))

 time n.risk n.event survival std.err lower 95% CI upper 95% CI 
   10      6       1    0.949  0.0732       0.8157            1
   20      4       2    0.694  0.2541       0.3385            1
   40      1       1    0.255  0.2718       0.0317            1
> summary(survfit(fit))
Call: survfit.coxph(object = fit)

 time n.risk n.event survival std.err lower 95% CI upper 95% CI 
    1      6       1   0.8857   0.117     0.683035            1
    2      4       2   0.4294   0.237     0.145743            1
    4      1       1   0.0425   0.116     0.000198            1
> # Tests of the weighted Cox model
> #
> # Similar data set to test1, but add weights,
> #                                    a double-death/censor tied time
> #                                    a censored last subject
> # The latter two are cases covered only feebly elsewhere.
> testw1 <- data.frame(time=  c(1,1,2,2,2,2,3,4,5),
+           status= c(1,0,1,1,1,0,0,1,0),
+           x=      c(2,0,1,1,0,1,0,1,0),
+           wt =    c(1,2,3,4,3,2,1,2,1))
> > fit0 <- coxph(Surv(time, status) ~x, testw1, weights=wt,
+           method="breslow", iter=0)
> fit  <- coxph(Surv(time, status) ~x, testw1, weights=wt, method="breslow")
> fit0
Call:
coxph(formula = Surv(time, status) ~ x, data = testw1, weights = wt, iter.max
     = 0, method = "breslow")


  coef exp(coef) se(coef) z p 
x    0         1    0.586 0 1

Likelihood ratio test=0  on 1 df, p=1  n= 9 
> summary(fit)
Call:
coxph(formula = Surv(time, status) ~ x, data = testw1, weights = wt, method = 
    "breslow")

  n= 9 

  coef exp(coef) se(coef)    z    p 
x 0.86      2.36    0.713 1.21 0.23

  exp(coef) exp(-coef) lower .95 upper .95 
x      2.36      0.423     0.584      9.56

Rsquare= 0.171   (max possible= 0.999 )
Likelihood ratio test= 1.69  on 1 df,   p=0.193
Wald test            = 1.45  on 1 df,   p=0.228
Score (logrank) test = 1.52  on 1 df,   p=0.217

> resid(fit0, type="mart")
         1           2         3         4         5          6          7 
 0.9473684 -0.05263158 0.3223684 0.3223684 0.3223684 -0.6776316 -0.6776316
          8         9 
 -0.3442982 -1.344298
> resid(fit0, type="score")
        1          2        3        4          5         6         7 
 1.246537 0.03601108 0.100567 0.100567 -0.2218014 -0.211933 0.4656986
          8        9 
 -0.1008219 0.910143
> resid(fit0, type="scho")
        1      2      2       2         4 
 1.315789 0.3125 0.3125 -0.6875 0.3333333
> fit0 <- coxph(Surv(time, status) ~x,testw1, weights=wt, iter=0)
> resid(fit0, "mart")
         1           2         3         4         5          6          7 
 0.9473684 -0.05263158 0.4445489 0.4445489 0.4445489 -0.8812657 -0.8812657
          8         9 
 -0.5479323 -1.547932
> resid(coxph(Surv(time, status) ~1, testw1, weights=wt))  #Null model
         1           2         3         4         5          6          7 
 0.9473684 -0.05263158 0.4445489 0.4445489 0.4445489 -0.8812657 -0.8812657
          8         9 
 -0.5479323 -1.547932
> > resid(fit, type="mart")
         1           2         3         4         5          6          7 
 0.8553129 -0.02593186 0.1763631 0.1763631 0.6513114 -0.8236369 -0.3486886
        8          9 
 -0.64894 -0.6980825
> resid(fit, type="score")
         1          2          3          4          5          6         7 
 0.8868191 0.02497664 0.03608986 0.03608986 -0.5429742 -0.1252885 0.2956474
           8         9 
 -0.09476947 0.5840033
> resid(fit, type="scho")
        1         2         2          2        4 
 1.036836 0.1613784 0.1613784 -0.8386216 0.174697
> > fit  <- coxph(Surv(time, status) ~x, testw1, weights=wt, method="efron")
> fit
Call:
coxph(formula = Surv(time, status) ~ x, data = testw1, weights = wt, method = 
    "efron")


   coef exp(coef) se(coef)    z    p 
x 0.873      2.39    0.713 1.22 0.22

Likelihood ratio test=1.75  on 1 df, p=0.186  n= 9 
> resid(fit, type="mart")
         1           2         3         4         5         6          7 
 0.8533465 -0.02560734 0.3226534 0.3226534 0.7169606 -1.077725 -0.4503436
          8          9 
 -0.9049011 -0.7959915
> resid(fit, type="score")
         1         2          3          4          5          6         7 
 0.8811638 0.0247726 0.06057842 0.06057842 -0.5972381 -0.1673716 0.3804048
          8         9 
 -0.1375035 0.6663165
> resid(fit, type="scho")
        1         2         2          2        4 
 1.032598 0.1621769 0.1621769 -0.8378231 0.172824
> # Tests of the weighted Cox model, AG form of the data
> #   Same solution as doweight1.s
> #
> testw2 <- data.frame(id  =  c( 1, 1, 2, 3, 3, 3, 4, 5, 5, 6, 7, 8, 8, 9),
+            begin= c( 0, 5, 0, 0,10,15, 0, 0,14, 0, 0, 0,23, 0),
+            time=  c( 5,10,10,10,15,20,20,14,20,20,30,23,40,50),
+           status= c( 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0),
+           x=      c( 2, 2, 0, 1, 1, 1, 1, 0, 0, 1, 0, 1, 1, 0),
+           wt =    c( 1, 1, 2, 3, 3, 3, 4, 3, 3, 2, 1, 2, 2, 1))
> > fit0 <- coxph(Surv(begin,time, status) ~x, testw2, weights=wt,
+           method="breslow", iter=0)
> fit  <- coxph(Surv(begin,time, status) ~x, testw2, weights=wt, method="breslow")
> fit0
Call:
coxph(formula = Surv(begin, time, status) ~ x, data = testw2, weights = wt, 
    iter.max = 0, method = "breslow")


  coef exp(coef) se(coef) z p 
x    0         1    0.586 0 1

Likelihood ratio test=0  on 1 df, p=1  n= 14 
> summary(fit)
Call:
coxph(formula = Surv(begin, time, status) ~ x, data = testw2, weights = wt, 
    method = "breslow")

  n= 14 

  coef exp(coef) se(coef)    z    p 
x 0.86      2.36    0.713 1.21 0.23

  exp(coef) exp(-coef) lower .95 upper .95 
x      2.36      0.423     0.584      9.56

Rsquare= 0.114   (max possible= 0.991 )
Likelihood ratio test= 1.69  on 1 df,   p=0.193
Wald test            = 1.45  on 1 df,   p=0.228
Score (logrank) test = 1.52  on 1 df,   p=0.217

> resid(fit0, type="mart", collapse=testw2$id)
         1           2         3         4         5          6          7 
 0.9473684 -0.05263158 0.3223684 0.3223684 0.3223684 -0.6776316 -0.6776316
          8         9 
 -0.3442982 -1.344298
> resid(fit0, type="score", collapse=testw2$id)
        1          2        3        4          5         6         7 
 1.246537 0.03601108 0.100567 0.100567 -0.2218014 -0.211933 0.4656986
          8        9 
 -0.1008219 0.910143
> resid(fit0, type="scho")
       10     20     20      20        40 
 1.315789 0.3125 0.3125 -0.6875 0.3333333
> > resid(fit, type="mart", collapse=testw2$id)
         1           2         3         4         5          6          7 
 0.8553129 -0.02593186 0.1763631 0.1763631 0.6513114 -0.8236369 -0.3486886
        8          9 
 -0.64894 -0.6980825
> resid(fit, type="score", collapse=testw2$id)
         1          2          3          4          5          6         7 
 0.8868191 0.02497664 0.03608986 0.03608986 -0.5429742 -0.1252885 0.2956474
           8         9 
 -0.09476947 0.5840033
> resid(fit, type="scho")
       10        20        20         20       40 
 1.036836 0.1613784 0.1613784 -0.8386216 0.174697
> fit0 <- coxph(Surv(begin, time, status) ~x,testw2, weights=wt, iter=0)
> resid(fit0, "mart", collapse=testw2$id)
         1           2         3         4         5          6          7 
 0.9473684 -0.05263158 0.4445489 0.4445489 0.4445489 -0.8812657 -0.8812657
          8         9 
 -0.5479323 -1.547932
> resid(coxph(Surv(begin, time, status) ~1, testw2, weights=wt)
+             , collapse=testw2$id)  #Null model
         1           2         3         4         5          6          7 
 0.9473684 -0.05263158 0.4445489 0.4445489 0.4445489 -0.8812657 -0.8812657
          8         9 
 -0.5479323 -1.547932
> > fit  <- coxph(Surv(begin,time, status) ~x, testw2, weights=wt, method="efron")
> fit
Call:
coxph(formula = Surv(begin, time, status) ~ x, data = testw2, weights = wt, 
    method = "efron")


   coef exp(coef) se(coef)    z    p 
x 0.873      2.39    0.713 1.22 0.22

Likelihood ratio test=1.75  on 1 df, p=0.186  n= 14 
> resid(fit, type="mart", collapse=testw2$id)
         1           2         3         4         5         6          7 
 0.8533465 -0.02560734 0.3226534 0.3226534 0.7169606 -1.077725 -0.4503436
          8          9 
 -0.9049011 -0.7959915
> resid(fit, type="score", collapse=testw2$id)
         1         2          3          4          5          6         7 
 0.8811638 0.0247726 0.06057842 0.06057842 -0.5972381 -0.1673716 0.3804048
          8         9 
 -0.1375035 0.6663165
> resid(fit, type="scho")
       10        20        20         20       40 
 1.032598 0.1621769 0.1621769 -0.8378231 0.172824
> #
> # The test data set from Turnbull, JASA 1974, 169-73.
> #
> #  status  0=right censored
> #          1=exact
> #          2=left censored
> #
> 
> turnbull <- data.frame( time  =c( 1,1,1, 2,2,2, 3,3,3, 4,4,4),
+           status=c( 1,0,2, 1,0,2, 1,0,2, 1,0,2),
+             n   =c(12,3,2, 6,2,4, 2,0,2, 3,3,5))
> #
> # Compute the K-M for the Turnbull data
> #      via a slow EM calculation
> #
> 
> emsurv <- function(time, status, wt, verbose=T) {
+     left.cen <- (status==2);+     if (!any(left.cen)) stop("No left censored data!");+     if (!any(status==1))stop("Must have some exact death times");+ 
+     tempy <- Surv(time[!left.cen], status[!left.cen]);+     ww <- wt[!left.cen];+     tempx <- factor(rep(1, sum(!left.cen)));+     tfit <- survfit.km(tempx, tempy, casewt=ww);+     if (verbose)
+        cat("Iteration 0, survival=", format(round(tfit$surv[tfit$n.event>0],3)),
+              "\n");+ 
+     stimes <- tfit$time[tfit$n.event>0];+     ltime <- time[left.cen];+     lwt   <- wt[left.cen];+     tempx <- factor(rep(1, length(stimes) + sum(!left.cen)));+     tempy <- Surv(c(time[!left.cen], stimes),
+         c(status[!left.cen], rep(1, length(stimes))));+     for (iter in 1:4) {
+   wt2 <- stimes*0;+   ssurv <- tfit$surv[tfit$n.event>0];+    sjump <- diff(c(1, ssurv));+    for (j in 1:(length(ltime))) {
+       k <- sum(ltime[j]>=stimes)   #index of the death time;+         if (k==0)
+       stop("Left censored observation before the first death");+      wt2[1:k] <- wt2[1:k] + lwt[j]*sjump[1:k] /(ssurv[k]-1);+        };+     tfit <- survfit.km(tempx, tempy, casewt=c(ww, wt2));+   if (verbose) {
+      cat("Iteration", iter, "survival=",
+        format(round(tfit$surv[tfit$n.event>0],3)),  "\n");+      cat("             weights=", format(round(wt2,3)), "\n");+      };+  };+     survfit(tempy ~ tempx, weights=c(ww, wt2));+     }
> > temp <-emsurv(turnbull$time, turnbull$status, turnbull$n)
Iteration 0, survival= 0.613 0.383 0.287 0.144 
Iteration 1 survival= 0.549 0.303 0.214 0.094 
             weights= 7.856 3.477 0.828 0.839 
Iteration 2 survival= 0.540 0.296 0.210 0.095 
             weights= 8.228 3.394 0.714 0.664 
Iteration 3 survival= 0.538 0.295 0.210 0.095 
             weights= 8.315 3.356 0.690 0.638 
Iteration 4 survival= 0.538 0.295 0.210 0.095 
             weights= 8.338 3.342 0.685 0.635 
> print(summary(temp))
Call: survfit(formula = tempy ~ tempx, weights = c(ww, wt2))

 time n.risk n.event survival std.err lower 95% CI upper 95% CI 
    1  44.00   20.34   0.5378  0.0752       0.4089        0.707
    2  20.66    9.34   0.2946  0.0719       0.1827        0.475
    3   9.32    2.68   0.2098  0.0673       0.1119        0.393
    4   6.64    3.64   0.0948  0.0507       0.0333        0.270
> #
> # Read in the ovarian data
> #
> 
> ovarian <- read.table("data.ovarian", row.names=NULL,
+       col.names= c("futime", "fustat", "age", "resid.ds", "rx", "ecog.ps"))
> #
> # Test the coxph program on the Ovarian data
> #
> 
> xx _ order(ovarian$futime)   #put data in same order as SAS green book
> temp <- ovarian[xx,]
> attach(temp)
> > # List the data
> temp
   futime fustat     age resid.ds rx ecog.ps 
 1     59      1 72.3315        2  1       1
 2    115      1 74.4932        2  1       1
 3    156      1 66.4658        2  1       2
22    268      1 74.5041        2  1       2
23    329      1 43.1370        2  1       1
24    353      1 63.2192        1  2       2
25    365      1 64.4247        2  2       1
26    377      0 58.3096        1  2       1
 4    421      0 53.3644        2  2       1
 5    431      1 50.3397        2  1       1
 6    448      0 56.4301        1  1       2
 7    464      1 56.9370        2  2       2
 8    475      1 59.8548        2  2       2
 9    477      0 64.1753        2  1       1
10    563      1 55.1781        1  2       2
11    638      1 56.7562        1  1       2
12    744      0 50.1096        1  2       1
13    769      0 59.6301        2  2       2
14    770      0 57.0521        2  2       1
15    803      0 39.2712        1  1       1
16    855      0 43.1233        1  1       2
17   1040      0 38.8932        2  1       2
18   1106      0 44.6000        1  1       1
19   1129      0 53.9068        1  2       1
20   1206      0 44.2055        2  2       1
21   1227      0 59.5890        1  2       2
> > summary(survfit(Surv(futime, fustat)), censor=T)
Call: survfit(formula = Surv(futime, fustat))

 time n.risk n.event survival std.err lower 95% CI upper 95% CI 
   59     26       1    0.962  0.0377        0.890        1.000
  115     25       1    0.923  0.0523        0.826        1.000
  156     24       1    0.885  0.0627        0.770        1.000
  268     23       1    0.846  0.0708        0.718        0.997
  329     22       1    0.808  0.0773        0.670        0.974
  353     21       1    0.769  0.0826        0.623        0.949
  365     20       1    0.731  0.0870        0.579        0.923
  377     19       0    0.731  0.0870        0.579        0.923
  421     18       0    0.731  0.0870        0.579        0.923
  431     17       1    0.688  0.0919        0.529        0.894
  448     16       0    0.688  0.0919        0.529        0.894
  464     15       1    0.642  0.0965        0.478        0.862
  475     14       1    0.596  0.0999        0.429        0.828
  477     13       0    0.596  0.0999        0.429        0.828
  563     12       1    0.546  0.1032        0.377        0.791
  638     11       1    0.497  0.1051        0.328        0.752
  744     10       0    0.497  0.1051        0.328        0.752
  769      9       0    0.497  0.1051        0.328        0.752
  770      8       0    0.497  0.1051        0.328        0.752
  803      7       0    0.497  0.1051        0.328        0.752
  855      6       0    0.497  0.1051        0.328        0.752
 1040      5       0    0.497  0.1051        0.328        0.752
 1106      4       0    0.497  0.1051        0.328        0.752
 1129      3       0    0.497  0.1051        0.328        0.752
 1206      2       0    0.497  0.1051        0.328        0.752
 1227      1       0    0.497  0.1051        0.328        0.752
> > # Various models
> coxph(Surv(futime, fustat)~ age)
Call:
coxph(formula = Surv(futime, fustat) ~ age)


     coef exp(coef) se(coef)    z      p 
age 0.162      1.18   0.0497 3.25 0.0012

Likelihood ratio test=14.3  on 1 df, p=0.000156  n= 26 
> coxph(Surv(futime, fustat)~ resid.ds)
Call:
coxph(formula = Surv(futime, fustat) ~ resid.ds)


         coef exp(coef) se(coef)   z     p 
resid.ds 1.21      3.35    0.672 1.8 0.072

Likelihood ratio test=3.76  on 1 df, p=0.0525  n= 26 
> coxph(Surv(futime, fustat)~ rx)
Call:
coxph(formula = Surv(futime, fustat) ~ rx)


     coef exp(coef) se(coef)     z    p 
rx -0.596     0.551    0.587 -1.02 0.31

Likelihood ratio test=1.05  on 1 df, p=0.305  n= 26 
> coxph(Surv(futime, fustat)~ ecog.ps)
Call:
coxph(formula = Surv(futime, fustat) ~ ecog.ps)


         coef exp(coef) se(coef)     z   p 
ecog.ps 0.398      1.49    0.586 0.679 0.5

Likelihood ratio test=0.47  on 1 df, p=0.494  n= 26 
> > coxph(Surv(futime, fustat)~ resid.ds + rx + ecog.ps)
Call:
coxph(formula = Surv(futime, fustat) ~ resid.ds + rx + ecog.ps)


           coef exp(coef) se(coef)      z     p 
resid.ds  1.347     3.844    0.680  1.980 0.048
      rx -0.749     0.473    0.595 -1.260 0.210
 ecog.ps  0.453     1.573    0.590  0.767 0.440

Likelihood ratio test=6.03  on 3 df, p=0.11  n= 26 
> coxph(Surv(futime, fustat)~ age + rx + ecog.ps)
Call:
coxph(formula = Surv(futime, fustat) ~ age + rx + ecog.ps)


          coef exp(coef) se(coef)     z      p 
    age  0.147     1.158   0.0463  3.17 0.0015
     rx -0.815     0.443   0.6342 -1.28 0.2000
ecog.ps  0.103     1.109   0.6064  0.17 0.8600

Likelihood ratio test=15.9  on 3 df, p=0.00118  n= 26 
> coxph(Surv(futime, fustat)~ age + resid.ds + ecog.ps)
Call:
coxph(formula = Surv(futime, fustat) ~ age + resid.ds + ecog.ps)


          coef exp(coef) se(coef)     z      p 
     age 0.142      1.15    0.052 2.740 0.0061
resid.ds 0.663      1.94    0.750 0.883 0.3800
 ecog.ps 0.166      1.18    0.615 0.271 0.7900

Likelihood ratio test=15.1  on 3 df, p=0.00173  n= 26 
> coxph(Surv(futime, fustat)~ age + resid.ds + rx)
Call:
coxph(formula = Surv(futime, fustat) ~ age + resid.ds + rx)


           coef exp(coef) se(coef)      z      p 
     age  0.129     1.137   0.0473  2.718 0.0066
resid.ds  0.696     2.006   0.7585  0.918 0.3600
      rx -0.849     0.428   0.6392 -1.328 0.1800

Likelihood ratio test=16.8  on 3 df, p=0.000789  n= 26 
> > # Residuals
> fit <- coxph(Surv(futime, fustat)~ age + resid.ds + rx + ecog.ps )
> resid(fit)
         1         2         3      22        23        24        25 
 0.8410328 0.5442439 0.5967083 -0.6548 0.9586613 0.8211167 0.5513655
          26          4         5          6         7         8         9 
 -0.09154016 -0.1128138 0.7511159 -0.3260903 0.5999893 0.2957072 -2.153258
        10         11         12        13         14          15         16 
 0.7624347 0.06474273 -0.1168075 -1.225628 -0.6347484 -0.07535826 -0.1705891
         17         18         19         20         21 
 -0.2298604 -0.1465486 -0.1876292 -0.1277155 -0.5337312
> resid(fit, "dev")
        1         2       3         22      23      24        25         26 
 1.412816 0.6950591 0.78916 -0.5497633 2.11059 1.34157 0.7073631 -0.4278789
          4        5         6         7         8         9      10 
 -0.4750027 1.131063 -0.807577 0.7953296 0.3312216 -2.075215 1.16179
         11         12        13       14         15         16         17 
 0.06619521 -0.4833375 -1.565649 -1.12672 -0.3882223 -0.5841046 -0.6780271
         18         19         20        21 
 -0.5413846 -0.6125834 -0.5054018 -1.033181
> resid(fit, "scor")
            age    resid.ds          rx     ecog.ps 
 1   2.26503312  0.05686358 -0.10565381 -0.42661687
 2   3.02525487  0.04641313 -0.08623664 -0.34821275
 3  -0.06851286  0.07131432 -0.13250360  0.06167529
22  -3.48057915 -0.03965964  0.07368850 -0.26669329
23 -14.86623701  0.28137018 -0.52279209 -0.43881150
24   3.96084302 -0.56566918  0.34648947  0.44907408
25   4.30025736  0.15241263  0.22417524 -0.20390438
26   0.31490645  0.07091765 -0.05212199  0.04845624
 4   0.94597636 -0.02541511 -0.06423497  0.05971730
 5  -5.41507108  0.21605963 -0.32258093 -0.39333909
 6   1.48999549  0.24899474  0.14035144 -0.15380665
 7  -0.68612390  0.13740892  0.28392480  0.29196504
 8   0.93116933  0.08428959  0.16040158  0.18430640
 9  -8.20092606 -0.51356176  0.95647604  1.11337106
10   0.95287551 -0.31078221  0.21463990  0.17363389
11   2.85526174  0.09417729 -0.14186604 -0.07586084
12   0.92721126  0.07495004 -0.05400752  0.07061579
13  -1.93962989 -0.43919870 -0.56668532 -0.48467672
14   0.63185377 -0.22745951 -0.29348439  0.38373602
15   1.41495229  0.04835394  0.04051536  0.04555770
16   2.54591219  0.10945918  0.09171494 -0.06745976
17   4.40282419 -0.08236954  0.12358138 -0.09089871
18   1.97071871  0.09403354  0.07878993  0.08859572
19   0.77692382  0.12039307 -0.08675288  0.11343091
20   1.76784314 -0.04576633 -0.05905097  0.07721018
21  -0.82272543  0.34247079 -0.24677772 -0.21106496
> resid(fit, "scho")
             age    resid.ds         rx    ecog.ps 
 59   2.69315678  0.06761161 -0.1256239 -0.5072536
115   5.36390193  0.08039118 -0.1493686 -0.6031317
156  -0.89877404  0.10683988 -0.1985109  0.1984379
268   6.95664457  0.12857952 -0.2389036  0.2388158
329 -15.73656567  0.28889884 -0.5367805 -0.4634169
353   4.06104424 -0.70587652  0.4535120  0.5282024
365   5.50035871  0.25348266  0.4796229 -0.4413864
431  -8.06809462  0.27490178 -0.4297023 -0.5248323
464  -2.15471513  0.23158423  0.5066040  0.4814387
475   0.57065101  0.25226661  0.5518479  0.5244351
563   0.06487254 -0.47274521  0.3319974  0.2747028
638   1.64752693 -0.50593435 -0.6446946  0.2939883
> > fit <- coxph(Surv(futime, fustat) ~ age + ecog.ps + strata(rx))
> summary(fit)
Call:
coxph(formula = Surv(futime, fustat) ~ age + ecog.ps + strata(rx))

  n= 26 

           coef exp(coef) se(coef)      z      p 
    age  0.1385     1.149    0.048  2.885 0.0039
ecog.ps -0.0967     0.908    0.630 -0.154 0.8800

        exp(coef) exp(-coef) lower .95 upper .95 
    age     1.149      0.871     1.045      1.26
ecog.ps     0.908      1.102     0.264      3.12

Rsquare= 0.387   (max possible= 0.874 )
Likelihood ratio test= 12.7  on 2 df,   p=0.00174
Wald test            = 8.43  on 2 df,   p=0.0148
Score (logrank) test = 12.2  on 2 df,   p=0.0022

> summary(survfit(fit))
Call: survfit.coxph(object = fit)

                rx=1 
 time n.risk n.event survival std.err lower 95% CI upper 95% CI 
   59     13       1    0.978  0.0266       0.9275            1
  115     12       1    0.951  0.0478       0.8620            1
  156     11       1    0.910  0.0760       0.7722            1
  268     10       1    0.861  0.1055       0.6776            1
  329      9       1    0.736  0.1525       0.4909            1
  431      8       1    0.627  0.1704       0.3680            1
  638      5       1    0.333  0.2296       0.0865            1

                rx=2 
 time n.risk n.event survival std.err lower 95% CI upper 95% CI 
  353     13       1    0.943  0.0560        0.839        1.000
  365     12       1    0.880  0.0812        0.735        1.000
  464      9       1    0.789  0.1143        0.594        1.000
  475      8       1    0.697  0.1350        0.477        1.000
  563      7       1    0.597  0.1494        0.366        0.975

> sfit <- survfit(fit, list(age=c(30,70), ecog.ps=c(2,3)))  #two columns
> sfit
Call: survfit.coxph(object = fit, newdata = list(age = c(30, 70), ecog.ps = c(2, 3)))

      n events mean se(mean) median 0.95LCL 0.95UCL 
rx=1 13      7  634     98.9     NA      NA      NA
rx=1 13      7  259     24.7    268     115      NA
rx=2 13      5  562     29.0     NA      NA      NA
rx=2 13      5  422      7.9    365     353      NA
> summary(sfit)
Call: survfit.coxph(object = fit, newdata = list(age = c(30, 70), ecog.ps = c(2, 3)))

                rx=1 
 time n.risk n.event survival1 survival2 
   59     13       1     0.999   0.87905
  115     12       1     0.999   0.74575
  156     11       1     0.998   0.57399
  268     10       1     0.996   0.41765
  329      9       1     0.992   0.16677
  431      8       1     0.988   0.06492
  638      5       1     0.973   0.00161

                rx=2 
 time n.risk n.event survival1 survival2 
  353     13       1     0.999    0.7093
  365     12       1     0.997    0.4739
  464      9       1     0.994    0.2494
  475      8       1     0.991    0.1207
  563      7       1     0.987    0.0489

> detach(w=2)
> > > # Test the robust=T option of coxph
> fit <- coxph(Surv(futime, fustat) ~ age + ecog.ps + rx, ovarian, robust=T)
> rr <- resid(fit, type="dfbeta")
> all.equal(as.vector(t(rr) %*% rr), as.vector(fit$var))
[1] T
> temp _ scan("data.jasa", what=list(id=0, b.mo=0, b.d=0, b.y=0,
+                      a.mo=0, a.d=0, a.y=0,
+                      t.mo=0, t.d=0, t.y=0,
+                      f.mo=0, f.d=0, f.y=0,
+                      fu.stat=0, surg=0, mismatch=0,
+                      hla.a2=0, mscore=0, reject=0))
> > temp3 _ mdy.date(temp$b.mo, temp$b.d, temp$b.y)
> temp4 _ mdy.date(temp$a.mo, temp$a.d, temp$a.y)
> temp5 _ mdy.date(temp$t.mo, temp$t.d, temp$t.y)
> temp6 _ mdy.date(temp$f.mo, temp$f.d, temp$f.y)
> > # Make sure that a particular idiocy is turned off: turning logicals into 
> # factors!
> as.data.frame.logical <- as.data.frame.vector
Warning messages:
  assigning "as.data.frame.logical" masks an object of the same name on
    database 5
> jasa <- data.frame( birth.dt=temp3, accept.dt=temp4, tx.date=temp5,
+           fu.date=temp6, fustat=temp$fu.stat,
+           surgery = temp$surg,  age= temp4-temp3,
+           futime = 1+temp6 - temp4, wait.time= 1+temp5 - temp4,
+           transplant = c(!is.na(temp5)),
+           mismatch=temp$mismatch, hla.a2=temp$hla.a2,
+           mscore = temp$mscore, reject=temp$reject)
> > row.names(jasa) <- temp$id
> > # The "1+" above causes us to match the analysis in Kalbfleisch and Prentice.
> #  Someone accepted and transplanted on the same day is assumed to have one
> #  day under the non-transplant risk.
> 
> rm(temp, temp3, temp4, temp5, temp6)
> > > > > expect <- survexp(futime ~ ratetable(age=(accept.dt - birth.dt), sex=1,
+       year=accept.dt), jasa, cohort=F, ratetable=survexp.uswhite)
> > survdiff(Surv(jasa$futime, jasa$fustat) ~ offset(expect))
Call:
survdiff(formula = Surv(jasa$futime, jasa$fustat) ~ offset(expect))

 Observed Expected     Z p 
       75    0.583 -96.9 0
> # Do a Stanford heart transplant data the way that K&P do
> #
> # Input - a data frame containing the raw data
> # Output- a data frame with multiple obs for the transplanted subjects
> #
> #  There are more efficient ways to do this than the "for" loop below, but
> #    this script is much more readable than any of them.
> #
> stan1 <- function(jasa) {
+     id <- row.names(jasa);+     tx _  1*(jasa$transplant);+     covar _ cbind(jasa$age/365.25 -48,
+         (jasa$accept.dt - mdy.date(10,1,1967))/365.25,
+         jasa$surgery);+     n _ length(tx)     #number in study;+     ntx _ sum(tx)      #number transplanted;+     # Per paragraph 2, p138, the patient who died on the day of transplant is
+     #   treated differently, for all others deaths are assumed to occur "earlier
+     #   in the day" than transplants.
+     special <- id ==38;+     wait _ jasa$wait.time;+     wait[special] _ wait[special] - .5;+ 
+     age <- year <- surgery <- transplant <- id2 <- double(n+ntx);+     start <- stop <- event <- double(n+ntx);+     ii <- 1;+     for (i in 1:n) {
+   age[ii] <- covar[i,1];+     year[ii] <- covar[i,2];+    surgery[ii] <- covar[i,3];+     transplant[ii] <- 0;+   id2[ii] <- id[i];+ 
+   if (tx[i])  { #transplanted  - 2 lines if data
+       start[ii] <- 0;+        stop[ii]  <- wait[i];+      event[ii] <- 0;+ 
+       ii <- ii+1;+        start[ii] <- wait[i];+      stop[ii]  <- jasa$futime[i];+       event[ii] <- jasa$fustat[i];+       age[ii] <- covar[i,1];+         year[ii] <- covar[i,2];+        surgery[ii] <- covar[i,3];+         transplant[ii] <- 1;+       id2[ii] <- id[i];+      };+     else {                             # one line of data
+       start[ii] <-0;+         stop[ii] <- jasa$futime[i];+        event[ii]<- jasa$fustat[i];+        };+     ii <- ii+1;+    };+ 
+     data.frame(start, stop, event, age, year, surgery,
+           transplant=factor(transplant), id=id2);+     }
> > jasa1 _ stan1(jasa)
> attach(jasa1)
> # Now fit the 6 models found in Kalbfleisch and Prentice, p139
> options(contrasts=c("contr.treatment", "contr.treatment"))
> sfit.1 _ coxph(Surv(start, stop, event)~ (age + surgery)*transplant,
+               method="breslow")
> sfit.2 _ coxph(Surv(start, stop, event)~ year*transplant,
+               method="breslow")
> sfit.3 _ coxph(Surv(start, stop, event)~ (age + year)*transplant,
+               method="breslow")
> sfit.4 _ coxph(Surv(start, stop, event)~ (year +surgery) *transplant,
+               method="breslow")
> sfit.5 _ coxph(Surv(start, stop, event)~ (age + surgery)*transplant + year ,
+               method="breslow")
> sfit.6 _ coxph(Surv(start, stop, event)~ age*transplant + surgery + year,
+               method="breslow")
> > summary(sfit.1)
Call:
coxph(formula = Surv(start, stop, event) ~ (age + surgery) * transplant, method
     = "breslow")

  n= 172 

                      coef exp(coef) se(coef)      z    p 
               age  0.0138     1.014   0.0181  0.763 0.45
           surgery -0.5457     0.579   0.6109 -0.893 0.37
        transplant  0.1181     1.125   0.3277  0.360 0.72
    age:transplant  0.0348     1.035   0.0273  1.276 0.20
surgery:transplant -0.2916     0.747   0.7582 -0.385 0.70

                   exp(coef) exp(-coef) lower .95 upper .95 
               age     1.014      0.986     0.979      1.05
           surgery     0.579      1.726     0.175      1.92
        transplant     1.125      0.889     0.592      2.14
    age:transplant     1.035      0.966     0.982      1.09
surgery:transplant     0.747      1.339     0.169      3.30

Rsquare= 0.07   (max possible= 0.969 )
Likelihood ratio test= 12.4  on 5 df,   p=0.0291
Wald test            = 11.6  on 5 df,   p=0.0402
Score (logrank) test = 12  on 5 df,   p=0.0345

> sfit.2
Call:
coxph(formula = Surv(start, stop, event) ~ year * transplant, method = 
    "breslow")


                  coef exp(coef) se(coef)      z     p 
           year -0.265     0.767    0.105 -2.518 0.012
     transplant -0.282     0.754    0.514 -0.549 0.580
year:transplant  0.136     1.146    0.141  0.967 0.330

Likelihood ratio test=8.61  on 3 df, p=0.035  n= 172 
> summary(sfit.3)
Call:
coxph(formula = Surv(start, stop, event) ~ (age + year) * transplant, method = 
    "breslow")

  n= 172 

                   coef exp(coef) se(coef)      z      p 
            age  0.0155     1.016   0.0173  0.895 0.3700
           year -0.2735     0.761   0.1058 -2.585 0.0097
     transplant -0.5884     0.555   0.5427 -1.084 0.2800
 age:transplant  0.0339     1.034   0.0279  1.211 0.2300
year:transplant  0.2013     1.223   0.1425  1.413 0.1600

                exp(coef) exp(-coef) lower .95 upper .95 
            age     1.016      0.985     0.982     1.051
           year     0.761      1.315     0.618     0.936
     transplant     0.555      1.801     0.192     1.609
 age:transplant     1.034      0.967     0.979     1.093
year:transplant     1.223      0.818     0.925     1.617

Rsquare= 0.083   (max possible= 0.969 )
Likelihood ratio test= 14.8  on 5 df,   p=0.0111
Wald test            = 13.8  on 5 df,   p=0.0172
Score (logrank) test = 14  on 5 df,   p=0.0153

> sfit.4
Call:
coxph(formula = Surv(start, stop, event) ~ (year + surgery) * transplant, 
    method = "breslow")


                     coef exp(coef) se(coef)      z     p 
              year -0.254     0.776    0.108 -2.356 0.018
           surgery -0.236     0.790    0.628 -0.376 0.710
        transplant -0.292     0.747    0.506 -0.577 0.560
   year:transplant  0.164     1.179    0.142  1.162 0.250
surgery:transplant -0.550     0.577    0.776 -0.709 0.480

Likelihood ratio test=12.3  on 5 df, p=0.0303  n= 172 
> sfit.5
Call:
coxph(formula = Surv(start, stop, event) ~ (age + surgery) * transplant + year, 
    method = "breslow")


                      coef exp(coef) se(coef)      z     p 
               age  0.0150     1.015   0.0176  0.851 0.390
           surgery -0.4192     0.658   0.6157 -0.681 0.500
        transplant  0.0772     1.080   0.3316  0.233 0.820
              year -0.1363     0.873   0.0710 -1.921 0.055
    age:transplant  0.0270     1.027   0.0271  0.995 0.320
surgery:transplant -0.2981     0.742   0.7580 -0.393 0.690

Likelihood ratio test=16.2  on 6 df, p=0.0127  n= 172 
> sfit.6
Call:
coxph(formula = Surv(start, stop, event) ~ age * transplant + surgery + year, 
    method = "breslow")


                  coef exp(coef) se(coef)      z     p 
           age  0.0152     1.015   0.0175  0.870 0.380
    transplant  0.0475     1.049   0.3222  0.147 0.880
       surgery -0.6212     0.537   0.3679 -1.689 0.091
          year -0.1361     0.873   0.0709 -1.919 0.055
age:transplant  0.0271     1.027   0.0271  0.998 0.320

Likelihood ratio test=16.1  on 5 df, p=0.00667  n= 172 
> > # Survival curve for the "average" subject
> summary(survfit(sfit.1))
Call: survfit.coxph(object = sfit.1)

 time n.risk n.event survival std.err lower 95% CI upper 95% CI 
    1    103       1    0.991 0.00941       0.9723        1.000
    2    102       3    0.963 0.01879       0.9268        1.000
    3     99       3    0.935 0.02493       0.8876        0.985
    5     96       2    0.917 0.02823       0.8629        0.974
    6     94       2    0.898 0.03113       0.8390        0.961
    8     92       1    0.889 0.03246       0.8273        0.955
    9     91       1    0.879 0.03370       0.8158        0.948
   12     89       1    0.870 0.03485       0.8043        0.941
   16     88       3    0.842 0.03783       0.7710        0.920
   17     85       1    0.832 0.03877       0.7598        0.912
   18     84       1    0.823 0.03959       0.7492        0.905
   21     83       2    0.805 0.04089       0.7290        0.890
   28     81       1    0.796 0.04144       0.7190        0.882
   30     80       1    0.787 0.04196       0.7090        0.874
   32     78       1    0.778 0.04245       0.6989        0.866
   35     77       1    0.769 0.04289       0.6890        0.857
   36     76       1    0.759 0.04330       0.6790        0.849
   37     75       1    0.750 0.04370       0.6691        0.841
   39     74       1    0.741 0.04406       0.6593        0.832
   40     72       2    0.722 0.04478       0.6396        0.816
   43     70       1    0.713 0.04512       0.6298        0.807
   45     69       1    0.704 0.04547       0.6199        0.799
   50     68       1    0.694 0.04580       0.6101        0.790
   51     67       1    0.685 0.04613       0.6003        0.782
   53     66       1    0.676 0.04645       0.5905        0.773
   58     65       1    0.666 0.04678       0.5807        0.765
   61     64       1    0.657 0.04711       0.5708        0.756
   66     63       1    0.647 0.04745       0.5609        0.747
   68     62       2    0.628 0.04812       0.5408        0.730
   69     60       1    0.619 0.04847       0.5306        0.721
   72     59       2    0.600 0.04916       0.5106        0.704
   77     57       1    0.590 0.04952       0.5003        0.695
   78     56       1    0.580 0.04988       0.4897        0.686
   80     55       1    0.569 0.05026       0.4790        0.677
   81     54       1    0.559 0.05062       0.4682        0.668
   85     53       1    0.549 0.05101       0.4573        0.658
   90     52       1    0.538 0.05140       0.4464        0.649
   96     51       1    0.528 0.05178       0.4353        0.639
  100     50       1    0.517 0.05217       0.4239        0.630
  102     49       1    0.506 0.05255       0.4125        0.620
  110     47       1    0.495 0.05295       0.4010        0.610
  149     45       1    0.483 0.05337       0.3894        0.600
  153     44       1    0.472 0.05380       0.3778        0.590
  165     43       1    0.461 0.05423       0.3661        0.581
  186     41       1    0.450 0.05466       0.3545        0.571
  188     40       1    0.439 0.05504       0.3430        0.561
  207     39       1    0.427 0.05541       0.3316        0.551
  219     38       1    0.416 0.05579       0.3200        0.541
  263     37       1    0.405 0.05614       0.3083        0.531
  285     35       2    0.381 0.05678       0.2850        0.511
  308     33       1    0.370 0.05705       0.2733        0.500
  334     32       1    0.358 0.05732       0.2616        0.490
  340     31       1    0.346 0.05755       0.2500        0.480
  343     29       1    0.334 0.05785       0.2378        0.469
  584     21       1    0.317 0.05882       0.2202        0.456
  675     17       1    0.297 0.06009       0.1997        0.442
  733     16       1    0.276 0.06110       0.1792        0.426
  852     14       1    0.253 0.06221       0.1562        0.410
  980     11       1    0.226 0.06332       0.1306        0.391
  996     10       1    0.201 0.06314       0.1084        0.372
 1032      9       1    0.177 0.06190       0.0890        0.351
 1387      6       1    0.150 0.05998       0.0683        0.328
> > # Survival curve for a subject of age 50, with prior surgery, tx at 6 months
> data <- data.frame(start=c(0,183), stop=c(183,3*365), event=c(1,1),
+          age=c(50,50),  surgery=c(1,1), transplant=c(0,1))
> summary(survfit(sfit.1, data, individual=T))
Call: survfit.coxph(object = sfit.1, newdata = data, individual = T)

 time n.risk n.event survival std.err lower 95% CI upper 95% CI 
    1    103       1  0.98769 0.01780     9.53e-01            1
    2    102       3  0.95150 0.05540     8.49e-01            1
    3     99       3  0.91564 0.09097     7.54e-01            1
    5     96       2  0.89180 0.11384     6.94e-01            1
    6     94       2  0.86811 0.13588     6.39e-01            1
    8     92       1  0.85629 0.14663     6.12e-01            1
    9     91       1  0.84449 0.15722     5.86e-01            1
   12     89       1  0.83264 0.16772     5.61e-01            1
   16     88       3  0.79759 0.19763     4.91e-01            1
   17     85       1  0.78574 0.20739     4.68e-01            1
   18     84       1  0.77425 0.21674     4.47e-01            1
   21     83       2  0.75216 0.23437     4.08e-01            1
   28     81       1  0.74102 0.24304     3.90e-01            1
   30     80       1  0.72986 0.25157     3.71e-01            1
   32     78       1  0.71859 0.26004     3.54e-01            1
   35     77       1  0.70740 0.26836     3.36e-01            1
   36     76       1  0.69623 0.27649     3.20e-01            1
   37     75       1  0.68508 0.28437     3.04e-01            1
   39     74       1  0.67395 0.29214     2.88e-01            1
   40     72       2  0.65191 0.30690     2.59e-01            1
   43     70       1  0.64092 0.31403     2.45e-01            1
   45     69       1  0.62985 0.32100     2.32e-01            1
   50     68       1  0.61889 0.32775     2.19e-01            1
   51     67       1  0.60798 0.33423     2.07e-01            1
   53     66       1  0.59720 0.34046     1.95e-01            1
   58     65       1  0.58633 0.34647     1.84e-01            1
   61     64       1  0.57549 0.35229     1.73e-01            1
   66     63       1  0.56462 0.35789     1.63e-01            1
   68     62       2  0.54280 0.36848     1.43e-01            1
   69     60       1  0.53181 0.37344     1.34e-01            1
   72     59       2  0.51031 0.38245     1.17e-01            1
   77     57       1  0.49939 0.38664     1.10e-01            1
   78     56       1  0.48819 0.39065     1.02e-01            1
   80     55       1  0.47691 0.39443     9.43e-02            1
   81     54       1  0.46556 0.39792     8.72e-02            1
   85     53       1  0.45416 0.40120     8.04e-02            1
   90     52       1  0.44281 0.40416     7.40e-02            1
   96     51       1  0.43131 0.40682     6.79e-02            1
  100     50       1  0.41964 0.40913     6.21e-02            1
  102     49       1  0.40796 0.41106     5.66e-02            1
  110     47       1  0.39623 0.41261     5.15e-02            1
  149     45       1  0.38451 0.41382     4.66e-02            1
  153     44       1  0.37287 0.41461     4.22e-02            1
  165     43       1  0.36123 0.41506     3.80e-02            1
  186     41       1  0.30934 0.36341     3.09e-02            1
  188     40       1  0.26422 0.32398     2.39e-02            1
  207     39       1  0.22454 0.29254     1.75e-02            1
  219     38       1  0.18973 0.26639     1.21e-02            1
  263     37       1  0.15917 0.24323     7.96e-03            1
  285     35       2  0.10980 0.20117     3.03e-03            1
  308     33       1  0.09033 0.18138     1.76e-03            1
  334     32       1  0.07368 0.16215     9.86e-04            1
  340     31       1  0.05969 0.14362     5.34e-04            1
  343     29       1  0.04755 0.12524     2.72e-04            1
  584     21       1  0.03414 0.10194     9.82e-05            1
  675     17       1  0.02272 0.07786     2.75e-05            1
  733     16       1  0.01448 0.05684     6.61e-06            1
  852     14       1  0.00828 0.03777     1.08e-06            1
  980     11       1  0.00409 0.02195     1.11e-07            1
  996     10       1  0.00194 0.01206     9.82e-09            1
 1032      9       1  0.00087 0.00622     7.14e-10            1
> > # These should all give the same answer
> j.age <- jasa$age/365.25 -48
> fit1 <- coxph(Surv(futime, fustat) ~ j.age, data=jasa)
> fit2 <- coxph(Surv(futime, fustat) ~ j.age, jasa, init=fit1$coef, iter=0)
> fit3 <- coxph(Surv(start, stop, event) ~ age)
> fit4 <- coxph(Surv(start, stop, event) ~ offset((age-fit3$means)*fit1$coef))
> s1 <- survfit(fit1, fit3$means)
> s2 <- survfit(fit2, fit3$means)
> s3 <- survfit(fit3)
> s4 <- survfit(fit4)
> > all.equal(s1$surv, s2$surv)
[1] T
> all.equal(s1$surv, s3$surv)
[1] T
> all.equal(s1$surv, s4$surv)
[1] T
> > # Still the same answer, fit multiple strata at once
> #  Strata 1 has independent coefs of strata 2, so putting in
> #    the other data should not affect it
> ll <- length(start)
> ss <- rep(0:1, c(ll,ll))
> fit <- coxph(Surv(rep(start,2), rep(stop,2), rep(event,2)) ~
+           rep(age,2)*strata(ss) + I(rep(age,2)^2*ss) )
> fit$coef[1] - fit3$coef
   rep(age, 2) 
 -1.040834e-17
> s4 <- survfit(fit, c(fit3$means, 0,0))
> all.equal(s4$surv[1:(s4$strata[1])],  s3$surv)
[1] T
> detach("jasa1")
> # A subset of some local data on lung cancer patients.  A useful internal test
> #  because it has multiple strata and lots of missing values.
> #
> 
> # inst = enrolling institution
> # sex  1=male  2=female
> # ph.ecog  physician's estimate of the ECOG performace score.  0=fully active,
> #              4=bedridden
> # ph.karno  physician's estimate of the Karnofsky score, a competitor to the
> #              ECOG ps.
> # pat.karno  patient's assesment of his/her Karnofsky score
> # meal.cal   # calories consumed at meals (exclude beverages and snacks)
> # wt.loss    weight loss in the last 6 months
> 
> 
> # 12/98: this is now part of the Splus distribution, but they call it
> #  "lung"
> cancer <- lung
> #
> # Test out all of the routines on a more complex data set
> #
> temp <- survfit(Surv(time, status) ~ ph.ecog, cancer)
> summary(temp, times=c(30*1:11, 365*1:3))
Call: survfit(formula = Surv(time, status) ~ ph.ecog, data = cancer)

1 observations deleted due to missing 
                ph.ecog=0 
 time n.risk n.event survival std.err lower 95% CI upper 95% CI 
   30     60       3    0.952  0.0268       0.9012        1.000
   60     58       2    0.921  0.0341       0.8562        0.990
   90     56       2    0.889  0.0396       0.8146        0.970
  120     56       0    0.889  0.0396       0.8146        0.970
  150     55       1    0.873  0.0419       0.7946        0.959
  180     52       2    0.841  0.0461       0.7553        0.936
  210     48       2    0.808  0.0498       0.7164        0.912
  240     45       0    0.808  0.0498       0.7164        0.912
  270     38       2    0.770  0.0543       0.6709        0.884
  300     33       2    0.727  0.0591       0.6203        0.853
  330     29       2    0.681  0.0637       0.5670        0.818
  365     22       6    0.535  0.0728       0.4100        0.699
  730      5      11    0.193  0.0707       0.0943        0.396

                ph.ecog=1 
 time n.risk n.event survival std.err lower 95% CI upper 95% CI 
   30    111       2    0.982  0.0124       0.9583        1.000
   60    110       3    0.956  0.0193       0.9186        0.994
   90    104       4    0.920  0.0255       0.8718        0.972
  120     99       5    0.876  0.0310       0.8174        0.939
  150     93       6    0.823  0.0359       0.7556        0.896
  180     82       8    0.751  0.0407       0.6756        0.836
  210     68       9    0.666  0.0450       0.5831        0.760
  240     57       6    0.604  0.0474       0.5176        0.704
  270     53       4    0.561  0.0487       0.4729        0.665
  300     46       3    0.527  0.0495       0.4384        0.633
  330     40       4    0.480  0.0504       0.3903        0.589
  365     34       4    0.431  0.0509       0.3417        0.543
  730      7      21    0.114  0.0388       0.0582        0.222

                ph.ecog=2 
 time n.risk n.event survival std.err lower 95% CI upper 95% CI 
   30     46       5   0.9000  0.0424      0.82057        0.987
   60     43       2   0.8600  0.0491      0.76900        0.962
   90     40       3   0.8000  0.0566      0.69647        0.919
  120     34       4   0.7174  0.0641      0.60216        0.855
  150     31       3   0.6541  0.0680      0.53342        0.802
  180     26       6   0.5275  0.0719      0.40385        0.689
  210     21       4   0.4431  0.0717      0.32266        0.608
  240     17       3   0.3766  0.0705      0.26100        0.543
  270     17       0   0.3766  0.0705      0.26100        0.543
  300     13       3   0.3102  0.0677      0.20223        0.476
  330     11       2   0.2624  0.0651      0.16135        0.427
  365      9       2   0.2147  0.0614      0.12258        0.376
  730      1       6   0.0371  0.0345      0.00601        0.229

                ph.ecog=3 
 time n.risk n.event survival std.err lower 95% CI upper 95% CI 
   30      1       0        1       0            1            1
   60      1       0        1       0            1            1
   90      1       0        1       0            1            1

> print(temp[2:3])
Call: survfit(formula = Surv(time, status) ~ ph.ecog, data = cancer)

   1 observations deleted due to missing 
            n events mean se(mean) median 0.95LCL 0.95UCL 
ph.ecog=1 113     82  385     27.3    306     268     429
ph.ecog=2  50     44  259     31.2    199     156     288
> > temp <- survfit(Surv(time, status), cancer, type="fleming",
+          conf.int=.9, conf.type="log-log", error="tsiatis")
> summary(temp, times=30 *1:5)
Call: survfit(formula = Surv(time, status), data = cancer, type = "fleming", conf.int
     = 0.9, conf.type = "log-log", error = "tsiatis")

 time n.risk n.event survival std.err lower 90% CI upper 90% CI 
   30    219      10    0.956  0.0135        0.928        0.974
   60    213       7    0.926  0.0173        0.891        0.950
   90    201      10    0.882  0.0213        0.842        0.913
  120    189      10    0.838  0.0244        0.793        0.874
  150    179      10    0.794  0.0268        0.745        0.834
> > temp <- survdiff(Surv(time, status) ~ inst, cancer, rho=.5)
> print(temp, digits=6)
Call:
survdiff(formula = Surv(time, status) ~ inst, data = cancer, rho = 0.5)

n=227, 1 observations deleted due to missing.

         N  Observed  Expected   (O-E)^2/E   (O-E)^2/V 
 inst=1 36 21.190058 17.455181 0.799149708 1.171232977
 inst=2  5  3.173330  1.964395 0.744007932 0.860140808
 inst=3 19 10.663476 11.958755 0.140294489 0.200472362
 inst=4  4  2.245347  3.559344 0.485085848 0.677874608
 inst=5  9  5.010883  4.500982 0.057765161 0.077128402
 inst=6 14  8.862602  7.078516 0.449665221 0.582743947
 inst=7  8  4.445647  4.416133 0.000197254 0.000253632
inst=10  4  2.901923  2.223283 0.207150016 0.249077097
inst=11 18  7.807867  9.525163 0.309611863 0.422142221
inst=12 23 14.009656 12.216768 0.263117640 0.365712493
inst=13 20  9.140983 11.863298 0.624699853 0.874238212
inst=15  6  3.170744  3.558447 0.042241456 0.057938955
inst=16 16  8.870360  9.992612 0.126038005 0.175170113
inst=21 13  9.263733  4.460746 5.171484268 6.149354145
inst=22 17  8.278566 11.971473 1.139171459 1.645863937
inst=26  6  1.627074  3.542694 1.035821659 1.286365543
inst=32  7  1.792468  2.679904 0.293869782 0.343966668
inst=33  2  0.929177  0.416202 0.632249272 0.676682390

 Chisq= 15.1  on 17 degrees of freedom, p= 0.590384 
> > temp <- coxph(Surv(time, status) ~ ph.ecog + ph.karno + pat.karno + wt.loss 
+         + sex + age + meal.cal + strata(inst), cancer)
> summary(temp)
Call:
coxph(formula = Surv(time, status) ~ ph.ecog + ph.karno + pat.karno + wt.loss + 
    sex + age + meal.cal + strata(inst), data = cancer)

  n=167 (61 observations deleted due to missing)

              coef exp(coef) se(coef)      z      p 
  ph.ecog  0.73000     2.075 0.268940  2.714 0.0066
 ph.karno  0.01305     1.013 0.013736  0.950 0.3400
pat.karno -0.01410     0.986 0.009368 -1.505 0.1300
  wt.loss -0.01488     0.985 0.008481 -1.755 0.0790
      sex -0.66125     0.516 0.233998 -2.826 0.0047
      age  0.00509     1.005 0.013729  0.371 0.7100
 meal.cal -0.00024     1.000 0.000302 -0.794 0.4300

          exp(coef) exp(-coef) lower .95 upper .95 
  ph.ecog     2.075      0.482     1.225     3.515
 ph.karno     1.013      0.987     0.986     1.041
pat.karno     0.986      1.014     0.968     1.004
  wt.loss     0.985      1.015     0.969     1.002
      sex     0.516      1.937     0.326     0.817
      age     1.005      0.995     0.978     1.033
 meal.cal     1.000      1.000     0.999     1.000

Rsquare= 0.167   (max possible= 0.912 )
Likelihood ratio test= 30.6  on 7 df,   p=7.38e-05
Wald test            = 28.1  on 7 df,   p=0.000207
Score (logrank) test = 30.7  on 7 df,   p=7e-05

> cox.zph(temp)
              rho  chisq      p 
  ph.ecog  0.0276 0.1078 0.7427
 ph.karno  0.1331 2.0018 0.1571
pat.karno  0.0250 0.0841 0.7718
  wt.loss -0.0386 0.2122 0.6451
      sex  0.0399 0.1800 0.6713
      age  0.0639 0.5600 0.4543
 meal.cal  0.1611 3.6945 0.0546
   GLOBAL      NA 9.0115 0.2518
> cox.zph(temp, transform="identity")
              rho   chisq     p 
  ph.ecog  0.0221  0.0688 0.793
 ph.karno  0.1217  1.6743 0.196
pat.karno  0.0302  0.1227 0.726
  wt.loss -0.0516  0.3790 0.538
      sex  0.0449  0.2280 0.633
      age  0.0719  0.7085 0.400
 meal.cal  0.1808  4.6537 0.031
   GLOBAL      NA 10.0537 0.186
> > coxph(Surv(rep(0,length(time)), time, status) ~ ph.ecog + ph.karno + pat.karno
+       + wt.loss + sex + age + meal.cal + strata(inst), cancer)
Call:
coxph(formula = Surv(rep(0, length(time)), time, status) ~ ph.ecog + ph.karno + 
    pat.karno + wt.loss + sex + age + meal.cal + strata(inst), data = 
    cancer)


              coef exp(coef) se(coef)      z      p 
  ph.ecog  0.73000     2.075 0.268940  2.714 0.0066
 ph.karno  0.01305     1.013 0.013736  0.950 0.3400
pat.karno -0.01410     0.986 0.009368 -1.505 0.1300
  wt.loss -0.01488     0.985 0.008481 -1.755 0.0790
      sex -0.66125     0.516 0.233998 -2.826 0.0047
      age  0.00509     1.005 0.013729  0.371 0.7100
 meal.cal -0.00024     1.000 0.000302 -0.794 0.4300

Likelihood ratio test=30.6  on 7 df, p=7.38e-05  n=167 (61 observations deleted due to missing)
> bladder <- read.table("data.bladder4",
+        col.names=c("id", "rx", "number", "size", "start", "stop",
+               "event", "enum"))
> > bladder2 <- bladder[bladder$start< bladder$stop, ]
> bladder$start <- NULL
> bladder <- bladder[bladder$enum<5,]
> #
> # Fit the models found in Wei et. al.
> #
> options(contrasts="contr.treatment")
> wfit <- coxph(Surv(stop, event) ~ (rx + size + number)* strata(enum) +
+        cluster(id), bladder, method="breslow")
> wfit
Call:
coxph(formula = Surv(stop, event) ~ (rx + size + number) * strata(enum) + 
    cluster(id), data = bladder, method = "breslow")


                            coef exp(coef) se(coef) robust se      z      p 
                      rx -0.5176     0.596   0.3158    0.3075 -1.683 0.0920
                    size  0.0679     1.070   0.1012    0.0853  0.796 0.4300
                  number  0.2360     1.266   0.0761    0.0721  3.275 0.0011
    rxstrata(enum)enum=2 -0.1019     0.903   0.5043    0.3265 -0.312 0.7600
    rxstrata(enum)enum=3 -0.1823     0.833   0.5579    0.3916 -0.465 0.6400
    rxstrata(enum)enum=4 -0.1328     0.876   0.6581    0.4968 -0.267 0.7900
  sizestrata(enum)enum=2 -0.1440     0.866   0.1680    0.1119 -1.287 0.2000
  sizestrata(enum)enum=3 -0.2792     0.756   0.2086    0.1511 -1.847 0.0650
  sizestrata(enum)enum=4 -0.2708     0.763   0.2514    0.1856 -1.459 0.1400
numberstrata(enum)enum=2 -0.0985     0.906   0.1193    0.1144 -0.861 0.3900
numberstrata(enum)enum=3 -0.0662     0.936   0.1298    0.1167 -0.567 0.5700
numberstrata(enum)enum=4  0.0930     1.098   0.1465    0.1175  0.792 0.4300

Likelihood ratio test=29.4  on 12 df, p=0.00344  n= 340 
> > # Check the rx coefs versus Wei, et al, JASA 1989
> rx <- c(1,4,5,6)  # the treatment coefs above
> cmat <- diag(4);
> cmat[1,] <- 1;
> #contrast matrix
> wfit$coef[rx] %*% cmat                   # the coefs in their paper (table 5)
           [,1]       [,2]       [,3]       [,4] 
[1,] -0.5175702 -0.6194396 -0.6998691 -0.6504161
> t(cmat) %*% wfit$var[rx,rx] %*% cmat  # var matrix (eqn 3.2)
           [,1]       [,2]       [,3]       [,4] 
[1,] 0.09455665 0.06017601 0.05677152 0.04376149
[2,] 0.06017601 0.13242841 0.13011523 0.11603238
[3,] 0.05677152 0.13011523 0.17235798 0.15906935
[4,] 0.04376149 0.11603238 0.15906935 0.23978095
> > # Anderson-Gill fit
> fita <- coxph(Surv(start, stop, event) ~ rx + size + number + cluster(id),
+         bladder2,  method="breslow")
> fita
Call:
coxph(formula = Surv(start, stop, event) ~ rx + size + number + cluster(id), 
    data = bladder2, method = "breslow")


          coef exp(coef) se(coef) robust se      z      p 
    rx -0.4071     0.666   0.2001    0.2418 -1.683 0.0920
  size -0.0401     0.961   0.0703    0.0722 -0.555 0.5800
number  0.1607     1.174   0.0480    0.0569  2.824 0.0047

Likelihood ratio test=14.1  on 3 df, p=0.00284  n= 190 
> > # Prentice fits.  Their model 1 a and b are the same
> fit1p  <- coxph(Surv(stop, event) ~ rx + size + number, bladder2,
+       subset=(enum==1), method="breslow")
> fit2pa <- coxph(Surv(stop, event) ~ rx + size + number, bladder2,
+       subset=(enum==2), method="breslow")
> fit2pb <- coxph(Surv(stop-start,  event) ~ rx + size + number, bladder2,
+          subset=(enum==2), method="breslow")
> fit3pa <- coxph(Surv(stop, event) ~ rx + size + number, bladder2,
+       subset=(enum==3), method="breslow")
> #and etc.
> fit1p
Call:
coxph(formula = Surv(stop, event) ~ rx + size + number, data = bladder2, subset
     = (enum == 1), method = "breslow")


          coef exp(coef) se(coef)      z      p 
    rx -0.5176     0.596   0.3158 -1.639 0.1000
  size  0.0679     1.070   0.1012  0.671 0.5000
number  0.2360     1.266   0.0761  3.103 0.0019

Likelihood ratio test=9.66  on 3 df, p=0.0216  n= 85 
> fit2pa
Call:
coxph(formula = Surv(stop, event) ~ rx + size + number, data = bladder2, subset
     = (enum == 2), method = "breslow")


           coef exp(coef) se(coef)       z    p 
    rx -0.42419     0.654   0.4022 -1.0547 0.29
  size -0.12496     0.883   0.1171 -1.0674 0.29
number  0.00199     1.002   0.0938  0.0212 0.98

Likelihood ratio test=2.02  on 3 df, p=0.569  n= 46 
> fit2pb
Call:
coxph(formula = Surv(stop - start, event) ~ rx + size + number, data = bladder2,
    subset = (enum == 2), method = "breslow")


           coef exp(coef) se(coef)       z    p 
    rx -0.25910     0.772   0.4051 -0.6396 0.52
  size -0.11621     0.890   0.1192 -0.9748 0.33
number -0.00571     0.994   0.0967 -0.0591 0.95

Likelihood ratio test=1.27  on 3 df, p=0.735  n= 46 
> fit3pa
Call:
coxph(formula = Surv(stop, event) ~ rx + size + number, data = bladder2, subset
     = (enum == 3), method = "breslow")


          coef exp(coef) se(coef)      z    p 
    rx -0.8985     0.407    0.554 -1.623 0.10
  size  0.0850     1.089    0.209  0.407 0.68
number -0.0172     0.983    0.128 -0.134 0.89

Likelihood ratio test=4.16  on 3 df, p=0.245  n= 27 
> #
> # A test of  NULL models
> #
> fit1 <- coxph(Surv(stop, event) ~ rx + strata(number), bladder, iter=0)
> fit2 <- coxph(Surv(stop, event) ~ strata(number), bladder)
> > all.equal(fit1$loglik[2], fit2$loglik)
[1] T
> all.equal(fit1$resid, fit2$resid)
[1] T
> > > fit1 <- coxph(Surv(start, stop, event) ~ rx + strata(number), bladder2, iter=0)
> fit2 <- coxph(Surv(start, stop, event) ~ strata(number), bladder2)
> > all.equal(fit1$loglik[2], fit2$loglik)
[1] T
> all.equal(fit1$resid, fit2$resid)
[1] T
> #  Tests of expected survival
> 
> #
> # Simple case 1: a single male subject, born 6/6/36 and entered on study 6/6/55.
> #
> #  Compute the 1, 5, 10 and 12 year expected survival
> 
> temp1 <- mdy.date(6,6,36)
> temp2 <- mdy.date(6,6,55)
> exp1 <- survexp(~ratetable(year=temp2, age=(temp2-temp1), sex=1),
+           ratetable=survexp.uswhite,times=c(366, 1827, 3653, 4383))
> > # Well, almost easy.  The uswhite table assumes that someone age 19 will have
> #   seen 5 leap years-- but this lad has only seen 4.  Thus the routine sees
> #   him as 1 day shy of his birthday.
> #   (The age 19 category starts at 6940, but he is 6939 days old at entry).
> # Thus his passage through the table is a bit more complicated
> 
> # First epoch:  1 day  at age 18, 1954    6/6/55
> #             365 days at age 19, 1955    6/7/55 - 6/5/56
> 
> # Second      365 days at age 20, 1956    6/6/56 - 6/5/57
> #             365 days at age 21, 1957    6/6/57 - 6/5/58
> #             366 days at age 22, 1958    6/6/58 - 6/6/59
> #             365 days at age 23, 1959    6/7/59 - 6/5/60
> 
> # Third       365 days at age 24, 1960    6/6/60 - 6/5/61
> #             365 days at age 25, 1961    6/6/61 - 6/5/62
> #             366 days at age 26, 1962    6/6/62 - 6/6/63
> #             365 days at age 27, 1963    6/7/63 - 6/5/64
> #             365 days at age 28, 1964    6/6/64 - 6/5/64
> 
> # Fourth      365 days at age 29, 1965    6/6/65 - 6/5/66
> #             365 days at age 30, 1966    6/6/66 - 6/5/67
> 
> # remember, a first subscript of "1" is for age 0
> 
> xx <- survexp.uswhite[,1,]
> check <- c(       (.6*xx[19,1] + .4*xx[19,2])    +
+        365* (.5*xx[20,1] + .5*xx[20,2]) ,
+ 
+        365* (.4*xx[21,1] + .6*xx[21,2]) +
+        365* (.3*xx[22,1] + .7*xx[22,2]) +
+        366* (.2*xx[23,1] + .8*xx[23,2]) +
+        365* (.1*xx[24,1] + .9*xx[24,2]) ,
+ 
+        365* (   xx[25,2]              ) +
+        365* (.9*xx[26,2] + .1*xx[26,3]) +
+        366* (.8*xx[27,2] + .2*xx[27,3]) +
+        365* (.7*xx[28,2] + .3*xx[28,3]) +
+        365* (.6*xx[29,2] + .4*xx[29,3]) ,
+ 
+        365* (.5*xx[30,2] + .5*xx[30,3]) +
+        365* (.4*xx[31,2] + .6*xx[31,3]) )
> > print(exp1$surv)
[1] 0.9984869 0.9917560 0.9840415 0.9808834
> print(exp(-cumsum(check)))
[1] 0.9984871 0.9917561 0.9840414 0.9808833
> > # This does not pass the "all.equal" test.  Because of leap year (again),
> #  the internal S code does not do exactly what is stated above.  US
> #  rate tables are special: the entry for age 20 in 1950 is the probability
> #  that someone who becomes 20 years old in 1950 will reach his 21st birthday.
> #  In order to fit this into the general "cutpoints" calculations of
> #  person-years, dates are adjusted so that everyone appears to have a
> #  birthday on Jan 1.  But because of leap years, a birthday then moves to
> #  Dec 31 sometimes --  this happens in each of the 366 day intervals above,
> #  e.g., 1 day at age 22 with 1957 rates, 365 at age 22 with 1958 rates.
> #  Upshot: they only agree to 6 decimals.  Close enough for me!
> 
> rm(temp1, temp2, exp1, check, xx)
> #  Tests of expected survival
> 
> #
> # Simple case 2: make sure that the averages are correct, for Ederer method
> #
> #  Compute the 1, 5, 10 and 12 year expected survival
> 
> temp1 <- mdy.date(1:6,6:11,36:41)
> temp2 <- mdy.date(6:1,11:6,55:50)
> age <- temp2 - temp1
> > exp1 <- survexp(~ratetable(year=temp2, age=(temp2-temp1), sex=1),
+              times=c(366, 1827, 3653, 4383))
> exp2 <- survexp(~ratetable(year=temp2, age=(temp2-temp1), sex=1) + I(1:6),
+           times=c(366, 1827, 3653, 4383))
> > print(all.equal(exp1$surv, apply(exp2$surv, 1, mean)))
[1] T
> > #
> # Check that adding more time points doesn't change things
> #
> exp3 <- survexp(~ratetable(year=temp2, age=(temp2-temp1), sex=1),
+       times=sort(c(366, 1827, 3653, 4383, 30*(1:100))))
> > exp1$surv
[1] 0.9989593 0.9939559 0.9859462 0.9823106
> exp3$surv[match(exp1$time, exp3$time, nomatch=0)]
[1] 0.9989593 0.9939559 0.9859462 0.9823106
> > > #
> # Now test Hakulinen's method, assuming an analysis date of 3/1/57
> #
> futime <- mdy.date(3,1,57) - temp2
> xtime  <- sort(c(futime, 30, 60, 185, 365))
> > exp1 <- survexp(futime ~ ratetable(year=temp2, age=(temp2-temp1), sex=1),
+       times=xtime, conditional=F)
> exp2 <- survexp(~ratetable(year=temp2, age=(temp2-temp1), sex=1) + I(1:6),
+           times=futime)
> > wt <- rep(1,6)
> con <- double(6)
> for (i in 1:6) {
+     con[i] <- sum(exp2$surv[i,i:6])/sum(wt[i:6]);+     wt <- exp2$surv[i,];+     }
> > exp1$surv[match(futime, xtime)]
[1] 0.9981627 0.9970156 0.9959044 0.9948167 0.9937561 0.9927036
> cumprod(con)                  #should be equal
[1] 0.9981627 0.9970156 0.9959044 0.9948167 0.9937561 0.9927036
> > > #
> # Now for the conditional method
> #
> exp1 <- survexp(futime ~ ratetable(year=temp2, age=(temp2-temp1), sex=1),
+       times=xtime, conditional=T)
> > cond <- exp2$surv
> for (i in 6:2) cond[i,] _ (cond[i,]/cond[i-1,])  #conditional survival
> for (i in 1:6) con[i] _ exp(mean(log(cond[i, i:6])))
> > all.equal(exp1$surv[match(futime, xtime)], cumprod(con))
[1] T
> cumprod(con)
[1] 0.9981625 0.9970151 0.9959036 0.9948157 0.9937550 0.9927025
> > rm(con, cond, exp1, exp2, wt, temp1, temp2, age)
> rm(exp3, futime, xtime)
> #
> # Test out expected survival, when the parent pop is another Cox model
> #
> fit <- coxph(Surv(time, status) ~x, test1, method="breslow")
> > dummy <- data.frame(time=c(.5, 1, 1.5, 2, 2.5, 3, 3.5, 4, 4.5),
+           status=c(1,0,1,0,1,0,1,1,1), x=(-4:4)/2)
> > efit <- survexp(time ~ ratetable(x=x), dummy, ratetable=fit, cohort=F)
> > #
> # Now, compare to the true answer, which is known to us
> #
> ss <- exp(fit$coef)
> haz <- c( 1/(3*ss+3), 2/(ss+3), 1) #truth at time 0,1,2,4+
> chaz <- cumsum(c(0,haz))
> chaz2 <- chaz[c(1,2,2,3,3,3,3,4,4)]
> > risk <- exp(fit$coef*dummy$x)
> efit2 <- exp(-risk*chaz2)
> > all.equal(as.vector(efit), as.vector(efit2))  #ignore mismatched name attrib
[1] T
> > #
> # Now test the direct-adjusted curve (Ederer)
> #
> efit <- survexp( ~ ratetable(x=x), dummy, ratetable=fit, se=F)
> direct <- survfit(fit, newdata=dummy)$surv
> > chaz <- chaz[-1]                  #drop time 0
> d2 <- exp(outer(-chaz, risk))
> all.equal(as.vector(direct), as.vector(d2))   #this tests survfit
[1] T
> > all.equal(as.vector(efit$surv), as.vector(apply(direct,1,mean)))  #direct
[1] T
> > > #
> # Now test out the Hakulinen method (Bonsel's method)
> #  By construction, we have a large correlation between x and censoring
> #
> # In theory, hak1 and hak2 would be the same.  In practice, like a KM and
> #   F-H, they differ when n is small.
> #
> efit <- survexp( time ~ ratetable(x=x), dummy, ratetable=fit, se=F)
> > surv  <- wt <- rep(1,9)
> tt <- c(1,2,4)
> hak1 <- hak2 <- NULL
> for (i in 1:3) {
+     wt[dummy$time < tt[i]]  <- 0;+     hak1 <- c(hak1,  exp(-sum(haz[i]*risk*surv*wt)/sum(surv*wt)));+     hak2 <- c(hak2,  sum(exp(-haz[i]*risk)*surv*wt)/sum(surv*wt));+     surv <- surv * exp(-haz[i]*risk);+     }
> > all.equal(as.vector(efit$surv), as.vector(cumprod(hak2)))
[1] T
> > #
> #  Now do the conditional estimate
> #
> efit <- survexp( time ~ ratetable(x=x), dummy, ratetable=fit, se=F,
+           conditional=T)
> wt <- rep(1,9)
> cond <- NULL
> for (i in 1:3) {
+     wt[dummy$time < tt[i]]  <- 0;+     cond <- c(cond,  exp(-sum(haz[i]*risk*wt)/sum(wt)));+     }
> > all.equal(as.vector(efit$surv), as.vector(cumprod(cond)))
[1] T
> > rm(wt, cond, efit, tt, surv, hak1, hak2)
> rm(fit, dummy, ss, efit2, chaz, chaz2, risk)
> rm(d2, direct)
> #
> # Run a test that can be verified using SAS's LIFEREG
> #
> fit1w <- survreg(Surv(time, status) ~x, test1, dist="weibull")
> fit1w
Call:
survreg(formula = Surv(time, status) ~ x, data = test1, dist = "weibull")

Coefficients:
 (Intercept)          x 
    1.293465 -0.7456443

Scale= 0.255742 

Loglik(model)= -4.9   Loglik(intercept only)= -7.1
    Chisq= 4.35 on 1 degrees of freedom, p= 0.037 
n=6 (1 observations deleted due to missing)
> summary(fit1w)

Call:
survreg(formula = Surv(time, status) ~ x, data = test1, dist = "weibull")
             Value Std. Error     z        p 
(Intercept)  1.293      0.181  7.15 8.57e-13
          x -0.746      0.257 -2.90 3.75e-03
 Log(scale) -1.364      0.392 -3.48 5.04e-04

Scale= 0.256 

Weibull distribution
Loglik(model)= -4.9   Loglik(intercept only)= -7.1
    Chisq= 4.35 on 1 degrees of freedom, p= 0.037 
Number of Newton-Raphson Iterations: 5 
n=6 (1 observations deleted due to missing)

Correlation of Coefficients:
           (Intercept)      x 
         x -0.705            
Log(scale)  0.016      -0.109

> > fit1e <- survreg(Surv(time, status) ~x, test1, dist="exp")
> fit1e
Call:
survreg(formula = Surv(time, status) ~ x, data = test1, dist = "exp")

Coefficients:
 (Intercept)          x 
    1.504077 -0.8109302

Scale fixed at 1 

Loglik(model)= -8.4   Loglik(intercept only)= -8.7
    Chisq= 0.64 on 1 degrees of freedom, p= 0.42 
n=6 (1 observations deleted due to missing)
> summary(fit1e)

Call:
survreg(formula = Surv(time, status) ~ x, data = test1, dist = "exp")
             Value Std. Error      z      p 
(Intercept)  1.504      0.707  2.127 0.0334
          x -0.811      1.000 -0.811 0.4174

Scale fixed at 1 

Exponential distribution
Loglik(model)= -8.4   Loglik(intercept only)= -8.7
    Chisq= 0.64 on 1 degrees of freedom, p= 0.42 
Number of Newton-Raphson Iterations: 3 
n=6 (1 observations deleted due to missing)

Correlation of Coefficients:
  (Intercept) 
x -0.707     

> > fit1l <- survreg(Surv(time, status) ~x, test1, dist="loglogistic")
> fit1l
Call:
survreg(formula = Surv(time, status) ~ x, data = test1, dist = "loglogistic")

Coefficients:
 (Intercept)         x 
    1.190922 -0.791701

Scale= 0.2159941 

Loglik(model)= -5.3   Loglik(intercept only)= -7.1
    Chisq= 3.62 on 1 degrees of freedom, p= 0.057 
n=6 (1 observations deleted due to missing)
> summary(fit1l)

Call:
survreg(formula = Surv(time, status) ~ x, data = test1, dist = "loglogistic")
             Value Std. Error     z        p 
(Intercept)  1.191      0.240  4.97 6.71e-07
          x -0.792      0.355 -2.23 2.59e-02
 Log(scale) -1.533      0.378 -4.05 5.13e-05

Scale= 0.216 

Log logistic distribution
Loglik(model)= -5.3   Loglik(intercept only)= -7.1
    Chisq= 3.62 on 1 degrees of freedom, p= 0.057 
Number of Newton-Raphson Iterations: 4 
n=6 (1 observations deleted due to missing)

Correlation of Coefficients:
           (Intercept)      x 
         x -0.671            
Log(scale)  0.047       0.040

> > fit1g <- survreg(Surv(time, status) ~x, test1, dist="lognormal")
> summary(fit1g)

Call:
survreg(formula = Surv(time, status) ~ x, data = test1, dist = "lognormal")
            Value Std. Error     z        p 
(Intercept)  1.16      0.215  5.39 7.08e-08
          x -0.77      0.308 -2.50 1.24e-02
 Log(scale) -1.07      0.344 -3.12 1.80e-03

Scale= 0.341 

Log Normal distribution
Loglik(model)= -5   Loglik(intercept only)= -7
    Chisq= 3.89 on 1 degrees of freedom, p= 0.049 
Number of Newton-Raphson Iterations: 5 
n=6 (1 observations deleted due to missing)

Correlation of Coefficients:
           (Intercept)      x 
         x -0.681            
Log(scale)  0.167      -0.016

> #
> #  Do a test with the ovarian data
> #
> fitfw <- survreg.old(Surv(futime, fustat) ~ age + ecog.ps, ovarian,
+   link="log", dist="extreme")
> fitfw
Call:
survreg(formula = formula, data = data, dist = dist, scale = scale)

Coefficients:
 (Intercept)         age    ecog.ps 
    12.28497 -0.09702669 0.09977342

Scale= 0.6032744 

Loglik(model)= -90   Loglik(intercept only)= -98
    Chisq= 15.98 on 2 degrees of freedom, p= 0.00034 
n= 26 
> > fitfl <- survreg.old(Surv(futime, fustat) ~ age + ecog.ps, ovarian,
+   link="log", dist="logistic")
> fitfl
Call:
survreg(formula = formula, data = data, dist = dist, scale = scale)

Coefficients:
 (Intercept)         age    ecog.ps 
    11.50853 -0.08876814 0.09033338

Scale= 0.4464063 

Loglik(model)= -89.5   Loglik(intercept only)= -97.4
    Chisq= 15.67 on 2 degrees of freedom, p= 4e-04 
n= 26 
> > flem2 <- scan("fleming.data2", what=list(ltime=0, rtime=0))
> flsurv<- Surv(flem2$ltime, flem2$rtime, type="interval2")
> > fitfw2 <- survreg(flsurv ~ age + ecog.ps, ovarian, dist="weibull")
> summary(fitfw2)

Call:
survreg(formula = flsurv ~ age + ecog.ps, data = ovarian, dist = "weibull")
               Value Std. Error      z        p 
(Intercept)  12.3870     1.5981  7.751 9.13e-15
        age  -0.0987     0.0253 -3.898 9.70e-05
    ecog.ps   0.1013     0.3773  0.269 7.88e-01
 Log(scale)  -0.4788     0.2582 -1.854 6.37e-02

Scale= 0.62 

Weibull distribution
Loglik(model)= -50.2   Loglik(intercept only)= -58
    Chisq= 15.62 on 2 degrees of freedom, p= 0.00041 
Number of Newton-Raphson Iterations: 5 
n= 26 

Correlation of Coefficients:
           (Intercept)    age ecog.ps 
       age -0.920                    
   ecog.ps -0.213      -0.170        
Log(scale)  0.444      -0.382 -0.114 

> > fitfl2 <- survreg(flsurv ~ age + ecog.ps, ovarian, dist="loglogistic")
> summary(fitfl2)

Call:
survreg(formula = flsurv ~ age + ecog.ps, data = ovarian, dist = "loglogistic")
               Value Std. Error      z        p 
(Intercept)  11.5250     1.5220  7.572 3.67e-14
        age  -0.0889     0.0239 -3.721 1.98e-04
    ecog.ps   0.0858     0.3626  0.237 8.13e-01
 Log(scale)  -0.8067     0.2706 -2.981 2.87e-03

Scale= 0.446 

Log logistic distribution
Loglik(model)= -49.8   Loglik(intercept only)= -57.6
    Chisq= 15.46 on 2 degrees of freedom, p= 0.00044 
Number of Newton-Raphson Iterations: 4 
n= 26 

Correlation of Coefficients:
           (Intercept)    age ecog.ps 
       age -0.920                    
   ecog.ps -0.293      -0.083        
Log(scale)  0.377      -0.368  0.018 

> > fitfg2 <- survreg(flsurv ~ age + ecog.ps, ovarian, dist="lognormal")
> summary(fitfg2)

Call:
survreg(formula = flsurv ~ age + ecog.ps, data = ovarian, dist = "lognormal")
               Value Std. Error      z        p 
(Intercept)  11.1575     1.4301  7.802 6.09e-15
        age  -0.0856     0.0237 -3.614 3.02e-04
    ecog.ps   0.2081     0.3815  0.545 5.85e-01
 Log(scale)  -0.2334     0.2507 -0.931 3.52e-01

Scale= 0.792 

Log Normal distribution
Loglik(model)= -50   Loglik(intercept only)= -57.5
    Chisq= 15.03 on 2 degrees of freedom, p= 0.00055 
Number of Newton-Raphson Iterations: 4 
n= 26 

Correlation of Coefficients:
           (Intercept)    age ecog.ps 
       age -0.906                    
   ecog.ps -0.197      -0.213        
Log(scale)  0.483      -0.440  0.008 

> #
> # A simple test of the singular=ok option
> #
> test1 <- data.frame(time=  c(4, 3,1,1,2,2,3),
+           status=c(1,NA,1,0,1,1,0),
+           x=     c(0, 2,1,1,1,0,0))
> > temp <- rep(0:3, rep(7,4))
> > stest <- data.frame(start  = 10*temp,
+           stop   = 10*temp + test1$time,
+           status = rep(test1$status,4),
+           x      = c(test1$x+ 1:7, rep(test1$x,3)),
+           epoch  = rep(1:4, rep(7,4)))
> > fit1 <- coxph(Surv(start, stop, status) ~ x * factor(epoch), stest)
Warning messages:
  X matrix deemed to be singular; variable 2 3 4 in: coxph(Surv(start, stop,
    status) ~ x * factor(epoch), stest)
> fit1$coef    # elements 2:4 should be NA
         x factor(epoch)2 factor(epoch)3 factor(epoch)4 xfactor(epoch)2 
 0.1041579             NA             NA             NA        1.572694
 xfactor(epoch)3 xfactor(epoch)4 
        1.572694        1.572694
> #
> # Test some more features of surv.diff
> #
> #  First, what happens when one group is a dummy
> #
> 
> 
> #
> # The AML data, with a third group of early censorings "tacked on"
> #
> aml3 <- list(time=   c( 9, 13, 13, 18, 23, 28, 31, 34, 45, 48, 161,
+              5,  5,  8,  8, 12, 16, 23, 27, 30, 33, 43, 45,
+              1,  2,  2,  3,  3,  3,  4),
+       status= c( 1,1,0,1,1,0,1,1,0,1,0, 1,1,1,1,1,0,1,1,1,1,1,1,
+               0,0,0,0,0,0,0),
+       x     = as.factor(c(rep("Maintained", 11),
+               rep("Nonmaintained", 12), rep("Dummy",7) )))
> > aml3 <- data.frame(aml3)
> > # These should give the same result (chisq, df), but the second has an
> #  extra group
> survdiff(Surv(time, status) ~x, aml)
Call:
survdiff(formula = Surv(time, status) ~ x, data = aml)

                 N Observed Expected (O-E)^2/E (O-E)^2/V 
   x=Maintained 11        7    10.69      1.27       3.4
x=Nonmaintained 12       11     7.31      1.86       3.4

 Chisq= 3.4  on 1 degrees of freedom, p= 0.0653 
> survdiff(Surv(time, status) ~x, aml3)
Call:
survdiff(formula = Surv(time, status) ~ x, data = aml3)

                 N Observed Expected (O-E)^2/E (O-E)^2/V 
        x=Dummy  7        0     0.00        NA        NA
   x=Maintained 11        7    10.69      1.27       3.4
x=Nonmaintained 12       11     7.31      1.86       3.4

 Chisq= 3.4  on 1 degrees of freedom, p= 0.0653 
> > > #
> # Now a test of the stratified log-rank
> #   There are no tied times within institution, so the coxph program
> #   can be used to give a complete test
> #
> fit <- survdiff(Surv(time, status) ~ pat.karno + strata(inst), cancer)
> > options(contrasts="contr.treatment")
> cfit <- coxph(Surv(time, status) ~ factor(pat.karno) + strata(inst),
+       cancer, iter=0)
> > tdata <- na.omit(cancer[,c("time", "status", "pat.karno", "inst")])
> > temp1 <- tapply(tdata$status-1, list(tdata$pat.karno, tdata$inst), sum)
> temp1 <- ifelse(is.na(temp1), 0, temp1)
> temp2 <- tapply(cfit$resid,  list(tdata$pat.karno, tdata$inst), sum)
> temp2 <- ifelse(is.na(temp2), 0, temp2)
> > temp2 <- temp1 - temp2
> > #Now temp1=observed, temp2=expected
> all.equal(c(temp1), c(fit$obs))
[1] T
> all.equal(c(temp2), c(fit$exp))
[1] T
> > all.equal(fit$var[-1,-1], solve(cfit$var))
[1] T
> > rm(tdata, temp1, temp2)
> # 
> # Simple case: a single male subject, born 6/6/36 and entered on study 6/6/55.
> #
> 
> temp1 <- mdy.date(6,6,36)
> temp2 <- mdy.date(6,6,55)# Now compare the results from person-years
> #
> temp.age <- tcut(temp2-temp1, floor(c(-1, (18:31 * 365.24))),
+   labels=c("0-18", paste(18:30, 19:31, sep="-")))
> temp.yr  <- tcut(temp2, mdy.date(1,1,1954:1965), labels=1954:1964)
> temp.time <- 3700   #total days of fu
> py1 <- pyears(temp.time ~ temp.age + temp.yr, scale=1) #output in days
> > # The subject should appear in 20 cells
> #    6/6/55 - 12/31/55, 209 days, age 19-20, 1955
> #    1/1/56 -  6/ 4/56, 156 days, age 19-20, 1956
> #    6/5/56 - 12/31/56, 210 days, age 20-21, 1956   (a leap year, and his
> #         birthday computes one day earlier)
> #    1/1/57 -  6/ 5/57, 156 days, age 20-21, 1957
> #    6/6/57 - 12/31/57, 209 days, age 21-22, 1957
> # and etc
> #   with 203 days "off table", ie, beyond the last cell of the table
> #
> # It is a nuisance, but tcut follows 'cut' in that we give the ENDS of
> #  the intervals, whereas the survival tables use the starts of intervals.
> #  Thus this breakdown does not match that in doexpect.s
> #
> xx <- matrix(0, nrow=14, ncol=11)
> xx[cbind(3:11, 3:11)] <- 156
> xx[cbind(3:12, 2:11)] <- c(209, 210, rep(c(209, 209, 209, 210),2))
> dimnames(xx) <- list(c("0-18", paste(18:30, 19:31, sep="-")), 1954:1964)
> all.equal(xx, py1$pyears)
[1] T
> all.equal(203, py1$offtable)
[1] T
> all.equal(1*(xx>0), py1$n)
[1] T
> > #
> # Now with expecteds
> #
> py2 <- pyears(temp.time ~ temp.age + temp.yr
+       + ratetable(age=temp2-temp1, year=temp2, sex=1),
+        scale=1, ratetable=survexp.uswhite ) #output in days
> all.equal(xx, py2$pyears)
[1] T
> all.equal(203, py2$offtable)
[1] T
> all.equal(1*(xx>0), py2$n)
[1] T
> > > py3 <-  pyears(temp.time ~ temp.age + temp.yr
+       + ratetable(age=temp2-temp1, year=temp2, sex=1),
+        scale=1, ratetable=survexp.uswhite , expect="pyears")
> all.equal(py2$n, py3$n)
[1] T
> all.equal(py2$pyear, py3$pyear)
[1] T
> all.equal(py3$n, 1*(py3$expect>0))
[1] T
> > # Now, compute the py3 result "by hand".  Since there is only one person
> #   it can be derived from py2.
> #
> xx1 <- py2$expect[py2$n>0]        # the hazard over each interval
> cumhaz <- cumsum(c(0, xx1[-length(xx1)]))     # the cumulative hazard 
> xx2 <- py3$expect[py3$n>0]        # the expected number of person days
> xx3 <- py3$pyears[py3$n>0]        # the potential number of person days
> > # This is the integral of the curve "exp(-haz *t)" over the interval
> integral <- xx3 * exp(-cumhaz)* (1- exp(-xx1))/ xx1
> # They might not be exactly equal, since the C code tracks changes in the
> #   rate tables that occur -within- an interval.  So try for 7 digits
> all.equal(round(integral,4), round(xx2,4))
[1] "Mean relative difference: 4.7713e-07"
> > # Cut off the bottom of the table, instead of the side
> temp.age <- tcut(temp2-temp1, floor(c(-1, (18:27 * 365.24))),
+   labels=c("0-18", paste(18:26, 19:27, sep="-")))
> > py4 <- eval(py3$call)
> all.equal(py4$pyear, py3$pyear[1:10,])
[1] T
> all.equal(py4$expect, py3$expect[1:10,])
[1] T
> > rm(xx1, xx2, xx3, cumhaz, temp1, temp2)
> rm(temp.age, temp.yr, temp.time, xx)
> #
> # Test out subscripting in the case of a coxph survival curve
> #
> fit <- coxph(Surv(time, status) ~ age + sex + meal.cal + strata(ph.ecog),
+       data=cancer)
> > surv1 <- survfit(fit)
> temp <- surv1[2:3]
> > which <- cumsum(surv1$strata)
> zed   <- (which[1]+1):(which[3])
> all.equal(surv1$surv[zed], temp$surv)
[1] T
> all.equal(surv1$time[zed], temp$time)
[1] T
> > #
> # Now a result with a matrix of survival curves
> #
> dummy <- data.frame(age=c(30,40,60), sex=c(1,2,2), meal.cal=c(500, 1000, 1500))
> surv2 <- survfit(fit, newdata=dummy)
> > zed <- 1:which[1]
> all.equal(surv2$surv[zed,1], surv2[1,1]$surv)
[1] T
> all.equal(surv2$surv[zed,2], surv2[1,2]$surv)
[1] T
> all.equal(surv2$surv[zed,3], surv2[1,3]$surv)
[1] T
> all.equal(surv2$surv[zed, ], surv2[1,1:3]$surv)
[1] T
> all.equal(surv2$surv[zed],   (surv2[1]$surv)[,1])
[1] T
> all.equal(surv2$surv[zed, ], surv2[1, ]$surv)
[1] T
> q()