###################################################################
### Hemant Ishwaran
###################################################################
### Test fixed linear constrasts for dependent U-statistics
### Based on DeLong, DeLong, and Pearson (1988). Biometrics.
###
### Works for multivariate ROC data; ie the setting where
### each individual is ranked by M different raters with
### no missing data [for case of missing data a bootstrap
### procedure is also available; please contact me]
###
###
### Function returns an object containing:
### -------------------------------------
### (1) area: ROC areas for each of M raters (Mx1)
### (2) test.statistic: test statistic value (lx1)
### (3) chi.square: chisquare value for overall test,
### degree of freedom,
### and p-value
### (4) Var: variance matrix for test statistic
###
### where contrast is a l x M contrast matrix representing
### the desired test (rank is <= M)
###
### Example Degree of suspicion of stage C/D prostate
### ------- cancer on ordinal scale {1,2,...100}. Each
### patient ranked by 5 different radiologists.
###
### -- true disease status for each patient (99 values):
###
### group <- c(
### 1,0,1,0,1,1,0,1,1,1,1,0,1,1,0,0,1,1,1,0,1,1,0,0,1,0,1,0,1,0,0,1,0,1,0,
### 0,0,1,1,0,0,1,0,0,0,1,0,0,1,0,0,1,0,1,0,0,0,0,0,0,0,0,1,1,0,1,1,0,1,1,
### 1,1,0,1,0,1,0,0,0,0,1,0,1,0,1,0,0,1,0,0,1,0,1,1,1,1,1,1,1)
###
### -- ordinal data for five readers (99x5):
###
### ordinal <- matrix(c(
### 99,90,100,100,100,5,5,10,25,49,40,25,95,75,65,20,20,20,15,50,10,35,50,
### 20,55,30,20,20,30,55,5,10,10,10,20,50,80,95,80,95,5,15,20,70,60,25,
### 35,60,100,80,50,5,35,50,30,5,40,10,15,10,60,75,90,75,95,10,30,10,60,
### 55,5,40,10,15,5,5,50,5,65,25,15,40,70,35,60,15,20,25,50,30,5,25,50,
### 20,10,5,5,10,10,10,40,95,100,100,95,60,30,60,30,51,5,0,5,5,1,5,10,25,
### 10,20,20,10,60,60,45,5,90,10,25,10,60,25,50,25,50,5,20,10,30,10,15,
### 60,85,25,45,5,20,40,60,30,5,25,10,60,55,30,10,10,30,10,25,20,50,25,
### 20,5,50,70,50,75,5,20,10,25,5,5,25,10,25,10,5,25,10,25,10,60,35,50,
### 35,65,40,20,20,20,30,5,80,10,40,20,5,25,20,25,5,10,90,50,20,65,10,15,
### 10,10,20,5,5,10,75,15,0,5,10,20,1,40,80,85,100,95,5,40,10,25,10,50,
### 25,25,25,40,5,5,25,0,15,5,5,25,25,10,5,60,20,60,35,70,80,100,100,45,
### 5,40,25,50,30,50,100,95,50,85,0,10,10,50,5,5,20,10,35,20,30,25,50,15,
### 55,10,30,30,75,10,20,20,10,75,10,60,80,60,100,5,5,25,10,30,25,10,35,
### 30,20,5,5,50,50,60,35,10,80,10,50,51,5,10,10,60,10,70,100,100,100,90,
### 10,20,10,70,5,15,20,25,100,90,40,60,25,100,55,10,10,10,10,55,80,75,
### 95,100,100,40,20,15,55,5,5,60,5,100,40,60,20,90,100,65,5,25,25,20,35,
### 60,50,30,40,50,5,10,50,10,65,10,25,10,20,25,10,5,15,50,10,50,60,25,
### 80,51,15,89,85,50,75,5,10,60,30,60,60,60,100,70,75,20,65,30,100,5,70,
### 80,85,70,85,10,25,10,100,35,5,20,10,10,10,30,70,50,100,30,10,20,5,50,
### 65,50,70,10,30,35,10,20,30,50,10,60,60,10,40,35,5,60,30,10,55,40,50,
### 20,100,65,50,50,95,70,90,80,80,100,100,100,5,20,40,15,35,15,65,45,30,
### 45,25,50,70,75,75),ncol=5,byrow=T)
###
### -- compute ROC areas and standard errors
###
### contrast.mat <- diag(5)
### prostate.out <- u.contrast(group,ordinal,contrast.mat)
### readers.area <- prostate.out$test
### readers.se <- sqrt(diag(prostate.out$Var))
###
### -- test if readers 1,2 and 3 are different than 4 and 5
### -- also test if readers 4 and 5 are different from one another
###
### contrast.mat2 <- rbind(c(1/3,1/3,1/3,-1/2,-1/2),c(0,0,0,1/2,-1/2))
### prostate.out2 <- u.contrast(group,ordinal,contrast.mat2)
### prostate.test <- prostate.out2$test
### prostate.pv <- prostate.out2$chi[3]
###
### -- from prostate.pv the overall p.value is 0.036
### -- signifying that we reject the null (no differences)
### -- also look at prostate.test for individual test statistics
###
###
### -------------------------------------------------------------
### Hemant Ishwaran ishwaran@bio.ri.ccf.org
### Dept of Biostatistics/Wb4 phone: 216-444-9932
### Cleveland Clinic Foundation fax: 216-445-2781
### 9500 Euclid Avenue
### Cleveland, OH 44195
###
### http://www.bio.ri.ccf.org/Resume/Pages/Ishwaran
###################################################################
### Function which computes U-statistics. Assign weight of
### 0.5 for ties.
ustat.con_function(neg,pos)
{
n.neg_length(neg)
n.pos_length(pos)
if (n.neg==1 | n.pos==1){ #labour saving device
sum((neg=ranked.cut[i])/n.neg
tp[i]_sum(pos>=ranked.cut[i])/n.pos
}
fp.diff_-diff(fp)
tp.mean_(tp[1:(n.atoms-1)] + tp[2:(n.atoms)])/2
sum(fp.diff*tp.mean)
}
}
u.contrast_function(group,ordinal,contrast)
{
M_dim(ordinal)[2]
group.uniq_unique(sort(group))
contrast_as.matrix(contrast)
n.neg_length(group[group==group.uniq[1]])
n.pos_length(group)-n.neg
Y_ordinal[(group==group.uniq[1]),c(1:M)] # Nondiseased group
X_ordinal[(group==group.uniq[2]),c(1:M)] # Diseased group
### Compute all areas (there are M of these)
theta_rep(0,M)
for (i in 1:M){
theta[i]_ustat.con(Y[,i],X[,i])
}
### Compute X,Y variance matrices
V01_matrix(0,n.neg,M,byrow=T)
V10_matrix(0,n.pos,M,byrow=T)
for (row in 1:n.neg){
for (col in 1:M){
V01[row,col]_ustat.con(Y[row,col],X[,col])
}
}
for (row in 1:n.pos){
for (col in 1:M){
V10[row,col]_ustat.con(Y[,col],X[row,col])
}
}
S01_(t(V01)%*%V01-n.neg*outer(theta,theta))/(n.neg-1)
S10_(t(V10)%*%V10-n.pos*outer(theta,theta))/(n.pos-1)
Svar_S10/n.pos+S01/n.neg
Var_contrast%*%Svar%*%t(contrast)
test.L_contrast%*%theta #Test value
test_t(test.L)%*%solve(Var)%*%test.L #Chisquare value
deg.f_min(dim(contrast))
chi.p_1-pchisq(test,deg.f)
### Return promised object:
return(list(area=theta,test.statistic=c(test.L),
chi.square=c(test,deg.f,chi.p),
Var=Var))
}