Nothing
library(coxme)
options(na.action='na.exclude', contrasts=c('contr.treatment', 'contr.poly'))
aeq <- function(x,y) all.equal(as.vector(x), as.vector(y))
#
# Test of fitting random slopes
#
# Simulation data with 9 institutions, strong age effects
# and a random treatment effect
#
set.seed(56)
n.subject <- seq(180, by=21, length=9) # number of subjects
slope <- sort(-.5 + rnorm(9, sd=.5)) # true treament effects
inst <- rep(1:9, n.subject)
n <- length(inst)
simdata <- data.frame(id=1:n, inst=inst,
trt= rep(0:1, length=n),
age= runif(n, 40, 70))
#risk goes up 30%/decade of age
simdata$hazard <- .8* exp(simdata$trt * rep(slope, n.subject) +
(simdata$age-55) * .03)
rtime <- function(hazard, censor=c(1,2)) {
stime <- rexp(length(hazard), rate=hazard)
ctime <- runif(length(hazard), censor[1], censor[2])
list(time= pmin(stime, ctime), status=1*(stime <=ctime))
}
temp <- rtime(simdata$hazard)
simdata$time <- temp$time
simdata$status <- temp$status
coef0 <- matrix(0., 2,9)
for (i in 1:9) {
fit0 <- coxph(Surv(time, status) ~ age + trt, simdata,
subset=(inst==i))
coef0[,i] <- fit0$coef
}
# Several of these fits will differ in the last few digits on a
# 64 bit vs 32 bit Intel processer. The loglike is very
# flat on top so tiny changes in the compute path lead to a small
# change in the final solution. Hence the "digits" argument.
fit0 <- coxph(Surv(time, status) ~ age + trt, simdata)
fit1 <- coxme(Surv(time, status) ~ age + trt + (1|inst), simdata)
print(fit1, rcoef=TRUE, digits=4)
fit2 <- coxme(Surv(time, status) ~ age + trt + (1|inst/trt), simdata)
print(fit2, rcoef=TRUE, digits=3)
# And so will this one
fit3 <- coxme(Surv(time, status) ~ age + trt + (1|inst) + (trt|inst),simdata)
print(fit3, rcoef=TRUE, digits=3)
fit4 <- coxme(Surv(time, status) ~ age + trt + (1 +trt |inst), simdata)
sfit0 <- coxph(Surv(time, status) ~ age + trt + strata(inst), simdata)
sfit1 <- coxme(Surv(time, status) ~ age + trt + (trt|inst) + strata(inst),
simdata)
print(sfit1, rcoef=TRUE, digits=4)
# Check that the start,stop code does the same
dummy <- runif(nrow(simdata), -4, -1) #all start times before first event
fit4b <- coxme(Surv(dummy, time, status) ~ age + trt + (1 +trt |inst), simdata)
all.equal(fit4b$loglik, fit4$loglik)
all.equal(fit4b$coef, fit4$coef, tolerance=1e-7) # different order of internal
# sums => tiny difference
#Comparison plot
y <- cbind(slope, NA, coef0[2,], fixef(sfit1)[2] + unlist(ranef(sfit1)),
fixef(fit3)[2] + ranef(fit3)[[2]],
fixef(fit4)[2] + ranef(fit4)[[1]][,2])
matplot(c(1, 1.5, 2:5), t(y), type='b', xaxt='n', xlab="Simulation",
ylab="Treatment coefficient", lty=1)
axis(1, 1:5, c("Sim", "Separate", "Strata", "Uncor", "Corr"))
#
# Now compute some things exactly
#
contr.none <- function(n,contrasts=T) {
if(is.numeric(n) && length(n) == 1.)
levs <- 1.:n
else {
levs <- n
n <- length(n)
}
contr <- array(0., c(n, n), list(levs, levs))
contr[seq(1., n^2., n + 1.)] <- 1.
contr
}
options(contrasts=c('contr.none', 'contr.poly'))
igchol <- function(x) {
dd <- diag(x)
ll <- as.matrix(x)
ll %*% diag(dd) %*% t(ll)
}
# For fit2
vtemp <- unlist(VarCorr(fit2))
names(vtemp) <- names(VarCorr(fit2))
fit2a <- coxme(Surv(time, status) ~ age + trt + (1|inst/trt), simdata,
iter=0, vfixed=vtemp)
temp <- strata(simdata$inst, simdata$trt, sep='/', shortlabel=TRUE)
cfit <- coxph(Surv(time, status) ~ factor(temp) +factor(inst) +age + trt,
simdata, iter=0, x=T)
dt2 <- coxph.detail(cfit)
u2 <- apply(dt2$score, 2, sum)
aeq(u2, fit2a$u)
imat2 <- apply(dt2$imat, 1:2, sum) + diag(c(rep(1/vtemp, c(18,9)),0,0))
aeq(imat2, as.matrix(igchol(fit2a$hmat)))
# For fit3
vtemp <- as.vector(unlist(VarCorr(fit3))) #name not needed
fit3a <- coxme(Surv(time, status) ~ age + trt + (1|inst) + (trt|inst),
simdata, iter=0, vfixed=as.list(vtemp))
cfit <- coxph(Surv(time, status) ~ factor(inst) * trt + age, simdata,
iter=0, x=T)
dt3 <- coxph.detail(cfit)
u3 <- apply(dt3$score, 2, sum)
indx <- c(1:9, 12:20, 11, 10)
aeq(u3[indx], fit3a$u)
imat2 <- apply(dt3$imat, 1:2, sum)[indx,indx] +
diag(c(rep(1/vtemp, c(9,9)),0,0))
aeq(imat2, as.matrix(igchol(fit3a$hmat)))
fit3b <- coxme(Surv(time, status) ~ age + trt + (trt|inst) +(1|inst),
simdata, iter=0, vfixed=as.list(rev(vtemp)))
aeq(fit3a$u, fit3b$u)
aeq(fit3b$imat, fit3b$imat)
#For sfit1
vtemp <- .0966
fit <- coxme(Surv(time, status) ~ age + trt + strata(inst) + (trt|inst),
simdata, iter=0, vfixed=vtemp)
cfit <- coxph(Surv(time, status) ~ factor(inst):trt + trt+ age+ strata(inst),
simdata, iter=0, x=T)
dt3 <- coxph.detail(cfit)
u3 <- apply(dt3$score, 2, sum)
indx <- c(3:11,2,1)
aeq(u3[indx], fit$u)
imat3 <- apply(dt3$imat,1:2, sum)[indx,indx] + diag(c(rep(1/vtemp,9),0,0))
aeq(imat3, as.matrix(igchol(fit$hmat)))
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.