## confidence intrervals ## library(methods) Drug<-c("Placebo","Aspirin") Infarction<-c("yes","no") table.3.1<-expand.grid(drug=Drug,infarction=Infarction) Data<-c(28,18,656,658) table.3.1<-cbind(table.3.1,count=Data) tapply(table.3.1$count,table.3.1[,1:2], sum) # wald confidence interval Wald.ci<-function(Table, aff.response, alpha=.05){ # Gives two-sided Wald CI's for odds ratio, difference in proportions and relative risk. # Table is a 2x2 table of counts with rows giving the treatment populations # aff.response is a string like "c(1,1)" giving the cell of the beneficial response and the treatment category # alpha is significance level pow<-function(x, a=-1) x^a z.alpha<-qnorm(1-alpha/2) if(is.character(aff.response)) where<-eval(parse(text=aff.response)) else where<-aff.response Next<-as.numeric(where==1) + 1 # OR odds.ratio<-Table[where[1],where[2]]*Table[Next[1],Next[2]]/(Table[where[1],Next[2]]*Table[Next[1],where[2]]) se.OR<-sqrt(sum(pow(Table))) ci.OR<-exp(log(odds.ratio) + c(-1,1)*z.alpha*se.OR) # difference of proportions p1<-Table[where[1],where[2]]/(n1<-Table[where[1],Next[2]] + Table[where[1],where[2]]) p2<-Table[Next[1],where[2]]/(n2<-Table[Next[1],where[2]]+Table[Next[1],Next[2]]) se.diff<-sqrt(p1*(1-p1)/n1 + p2*(1-p2)/n2) ci.diff<-(p1-p2) + c(-1,1)*z.alpha*se.diff # relative risk RR<-p1/p2 se.RR<-sqrt((1-p1)/(p1*n1) + (1-p2)/(p2*n2)) ci.RR<-exp(log(RR) + c(-1,1)*z.alpha*se.RR) list(OR=list(odds.ratio=odds.ratio, CI=ci.OR), proportion.difference=list(diff=p1-p2, CI=ci.diff), relative.risk=list(relative.risk=RR,CI=ci.RR)) } Wald.ci(temp, "c(1, 1)") # or use Wald.ci(temp, c(1, 1)) # score confidence interval gfun<-function(p,y0){ sum((c(-(28/p[1])+(656/(1-p[1]))-p[3], -(18/p[2])+(658/(1-p[2]))+p[3], p[1]-p[2])-y0)^2) } optim(fn=gfun,par=c(28/(28+656),18/(18+658),7), method="BFGS",y0=c(0,0,-.1),control=list(trace=2,REPORT=10)) score.ci<-function(Delta) { temp<-optim(fn=gfun,par=c(28/(28+656),18/(18+658),7), method="BFGS",y0=c(0,0,Delta), control=list(ndeps=c(rep(.000000001,3)))) p<-temp$par[1:2] z<-(p[1]-p[2]-Delta)/sqrt(p[1]*(1-p[1])/684 + p[2]*(1-p[2])/676) } Delta<-seq(-.2,.2,.0005) Delta<-seq(-.05,.05,.0001) z<-sapply(Delta,score.ci) Delta[abs(z)< qnorm(.975)] # profile likelihood ci library(Bhat) # neg. log-likelihood of "new" multinomial model nlogf <- function (p) { p1p<-p[1] pp1<-p[2] theta<-p[3] n11 <- table.3.1$count[1] n21<-table.3.1$count[2] n12<-table.3.1$count[3] n22<-table.3.1$count[4] p22<-(-1 + p1p + pp1 + 2*theta - (p1p + pp1)*theta - sqrt(-4*p1p*(-1 + pp1)*(-1 + theta) + (1 + p1p + pp1*(-1 + theta) - p1p*theta)^2))/(2*(-1 + theta)) p11 <- (1 + p1p*(-1 + theta) + pp1*(-1 + theta) - sqrt(-4*p1p*(-1 + pp1)*(-1 + theta) + (1 + p1p + pp1*(-1 + theta) - p1p*theta)^2))/(2*(-1 + theta)) p21 <- (-1 + p1p + pp1*(-1 + theta) - p1p*theta + sqrt(-4*p1p*(-1 + pp1)*(-1 + theta) + (1 + p1p + pp1*(-1 + theta) - p1p*theta)^2))/(2*(-1 + theta)) p12 <- (-1 + pp1 + p1p*(-1 + theta) - pp1*theta + sqrt(-4*p1p*(-1 + pp1)*(-1 + theta) + (1 + p1p + pp1*(-1 + theta) - p1p*theta)^2))/(2*(-1 + theta)) -(n11*log(p11) + n12*log(p12) + n21*log(p21) + n22*log(p22)) } # check answer with MLEs nlogf(c((28+656)/(684+676),(28+18)/(684+676),28*658/(18*656))) # neg LLH of multinomial logLH<-function(p){ n11 <- table.3.1$count[1] n21<-table.3.1$count[2] n12<-table.3.1$count[3] n22<-table.3.1$count[4] p11<-p[1] p12<-p[2] p21<-p[3] -(n11*log(p11) + n12*log(p12) + n21*log(p21) + n22*log(1-p11-p12-p21)) } # check answer with MLEs logLH(c(28/(684+676), 656/(684+676),18/(684+676))) # check MLEs are what we expect x <- list(label=c("p11","p12","p21"),est=c(28/(684+676),656/(684+676),18/(684+676)), low=c(0.001,0.001,0.001),upp=c(1,1,1)) dfp(x,f=logLH) # Now get CI on theta x <- list(label=c("p1p","pp1","theta"),est=c((28+656)/(684+676),(28+18)/(684+676),1.56),low=c(0,0,0),upp=c(1,1,100)) plkhci(x,nlogf,"theta") ## Tests of Independence ## # Table 3.2 (p.80) # set up data and expected counts religion.counts<-c(178,138,108,570,648,442,138,252,252) table.3.2<-cbind(expand.grid(list(Religious.Beliefs=c("Fund", "Mod", "Lib"), Highest.Degree=c("= S-PLUS 6.0) if(is.null(version$language) && inherits(x, "crosstabs")) { oldClass(x)<-NULL; attr(x, "marginals")<-NULL} n <- nrow(x) m <- ncol(x) pi.c<-pi.d<-matrix(0,nr=n,nc=m) row.x<-row(x) col.x<-col(x) for(i in 1:(n)){ for(j in 1:(m)){ pi.c[i, j]<-sum(x[row.xi & col.x>j]) pi.d[i, j]<-sum(x[row.xj]) + sum(x[row.x>i & col.x