Example code in R for performing isotonic regressions and Jonckheere-Terpstra test
( taken from here.)
Example data and reading into R
grp <- c(rep(0,6),rep(1,6),rep(2,6)) dat <- c(40,35,38,43,44,41,38,40,47,44,40,42,48,40,45,43,46,44) 0 40 0 35 0 38 0 43 0 44 0 41 1 38 1 40 1 47 1 44 1 40 1 42 2 48 2 40 2 45 2 43 2 46 2 44
Alternatively you can just use a single series of data
grp <- c(1:10) dat <- c(5,9,1,2,5,6,7,8,3,8)
NUMBER IS DAT (RESPONSE) AND INFORMATION ID THE GRP (OR GROUP) IN THE BELOW SCATTERPLOT
dat <- number grp <- as.ordered(information) R statements stripchart(grp ~ dat, method = "stack") stripchart(information ~ number, method = "stack")
The isotonic regression can then be performed in R by running the R syntax below
dat <- number grp <- as.ordered(information) mu0 <- mean(dat) sig0 <- sd(dat) n <- length(dat) ss.null <- sum((dat - mu0)^2) xbar <- sapply(split(dat, grp), mean) nbar <- sapply(split(dat, grp), length) k <- length(xbar) pava <- function(x, w) { if (any(w <= 0)) stop("weights must be positive") if (length(x) != length(w)) stop("arguments not same length") n <- length(x) design <- diag(n) repeat { out <- lm(x ~ design + 0, weights = w) mu <- coefficients(out) dmu <- diff(mu) if (all(dmu >= 0)) break j <- min(seq(along = dmu)[dmu < 0]) design[ , j] <- design[ , j] + design[ , j + 1] design <- design[ , - (j + 1), drop = FALSE] } return(as.numeric(design %*% mu)) } test.stat <- function(x, w) { mu <- pava(x, w) mu0 <- sum(w * x) / sum(w) ss.alt <- sum(w * (x - mu)^2) ss.null <- sum(w * (x - mu0)^2) return(ss.null - ss.alt) } print(tstat <- test.stat(xbar, nbar)) print(mu) nsim <- 1e3 - 1 tsim <- double(nsim) for (i in 1:nsim) { xbarsim <- rnorm(k, mu0, sig0 / sqrt(nbar)) tsim[i] <- test.stat(xbarsim, nbar) } phat <- mean(tsim >= tstat) (nsim * phat + 1) / (nsim + 1) nsim / (nsim + 1) * sqrt(phat * (1 - phat) / nsim) cat("Calculation took", proc.time()[1], "seconds\n")
and the Jonckheere-Terpstra test can be performed using the R code below
dat <- number grp <- as.ordered(information) jkstat <- function(x, g) { foo <- (sign(outer(x, x, "-")) + 1) / 2 sum(foo[g[row(foo)] > g[col(foo)]]) } print(jstat <- jkstat(dat, grp))
The results agree for this data set with ISOREG which was brought int to do isotonic regression after the R code in the other files was written. There are breaks at N=5 and N=9 giving
print(mu) [1] 4.25 4.25 4.25 4.25 5.00 6.00 6.00 6.00 6.00 8.00
The main lesson here is that the normal theory test (isotonic regression) does more or less the same as the nonparametric Jonckheere-Terpstra test. This is no surprise since the data are fairly normal looking.