Large-sample score confidence interval for a difference of proportions in 2x2 table (Mee 1984, Miettinen and Nurminen 1985, Nurminen 1986)
----------------------------------------------------------------------------- diffscoreci <- function(x1,n1,x2,n2,conflev){ px = x1/n1 py = x2/n2 z = qchisq(conflev,1) proot = px-py dp = 1-proot niter = 1 while(niter <= 50){ dp = 0.5*dp up2 = proot+dp score = z2stat(px,n1,py,n2,up2) if(score<z){ proot = up2 } niter = niter+1 if((dp<0.0000001) || (abs(z-score)<.000001)){ niter = 51 ul = up2} } proot = px-py dp = 1+proot niter = 1 while(niter <= 50){ dp = 0.5*dp low2 = proot-dp score = z2stat(px,n1,py,n2,low2) if(score<z){ proot = low2 } niter = niter+1 if((dp<0.0000001) || (abs(z-score)<.000001)){ ll = low2 niter = 51} } c(ll,ul) } z2stat <- function (p1x,nx,p1y,ny,dif){ diff = p1x-p1y-dif if ( abs(diff) == 0 ) { fmdiff = 0} else{ t = ny/nx a = 1+t b = -(1+ t + p1x + t*p1y + dif*(t+2)) c = dif*dif + dif*(2*p1x + t +1) + p1x + t*p1y d = -p1x*dif*(1+dif) v = (b/a/3)^3 - b*c/(6*a*a) + d/a/2 s = sqrt( (b/a/3)^2 - c/a/3) if(v>0){u=s} else{u=-s} w = (3.141592654+acos(v/u^3))/3 p1d = 2*u*cos(w) - b/a/3 p2d = p1d - dif var = p1d*(1-p1d)/nx + p2d*(1-p2d)/ny fmdiff = diff^2/var } return(fmdiff) } # Computes the score two-sample interval for (p1 - p2) # with success counts x1, x2 and trials n1, n2 # and with confidence coefficient = conflev # written by Yongyi Min -----------------------------------------------------------------------------
Wald confidence interval for difference of proportions in 2x2 table
----------------------------------------------------------------------------- wald2ci <- function(x1, n1, x2, n2, conflev){ p1hat = x1/n1 p2hat = x2/n2 z = abs(qnorm((1-conflev)/2)) ll = (p1hat - p2hat) - z*sqrt((p1hat*(1-p1hat))/n1 + (p2hat*(1-p2hat))/n2) ul = (p1hat - p2hat) + z*sqrt((p1hat*(1-p1hat))/n1 + (p2hat*(1-p2hat))/n2) c(ll,ul) } #Computes the Wald two-sample interval for (p1 - p2) #with success counts x1, x2 and trials n1, n2 #and with confidence coeff conflev. Returns a #list with the lower and upper end points #in that order. Add 1 to x1 and x2 and add 2 to n1 and n2 #to get Agresti-Caffo adjusted CI (American Statistician, 2000). -----------------------------------------------------------------------------
R Code for large-sample score confidence interval for a relative risk in a 2x2 table (Koopman 1984, Miettinen and Nurminen 1985, Nurminen 1986).
----------------------------------------------------------------------------- riskscoreci <- function(x1,n1,x2,n2,conflev) { z = abs(qnorm((1-conflev)/2)) if ((x2==0) &&(x1==0)){ ul = Inf ll = 0 } else{ a1 = n2*(n2*(n2+n1)*x1+n1*(n2+x1)*(z^2)) a2 = -n2*(n2*n1*(x2+x1)+2*(n2+n1)*x2*x1+n1*(n2+x2+2*x1)*(z^2)) a3 = 2*n2*n1*x2*(x2+x1)+(n2+n1)*(x2^2)*x1+n2*n1*(x2+x1)*(z^2) a4 = -n1*(x2^2)*(x2+x1) b1 = a2/a1 b2 = a3/a1 b3 = a4/a1 c1 = b2-(b1^2)/3 c2 = b3-b1*b2/3+2*(b1^3)/27 ceta = acos(sqrt(27)*c2/(2*c1*sqrt(-c1))) t1 = -2*sqrt(-c1/3)*cos(pi/3-ceta/3) t2 = -2*sqrt(-c1/3)*cos(pi/3+ceta/3) t3 = 2*sqrt(-c1/3)*cos(ceta/3) p01 = t1-b1/3 p02 = t2-b1/3 p03 = t3-b1/3 p0sum = p01+p02+p03 p0up = min(p01,p02,p03) p0low = p0sum-p0up-max(p01,p02,p03) if( (x2==0) && (x1!=0) ){ ll = (1-(n1-x1)*(1-p0low)/(x2+n1-(n2+n1)*p0low))/p0low ul = Inf } else if( (x2!=n2) && (x1==0)){ ul = (1-(n1-x1)*(1-p0up)/(x2+n1-(n2+n1)*p0up))/p0up ll = 0 } else if( (x2==n2) && (x1==n1)){ ul = (n2+z^2)/n2 ll = n1/(n1+z^2) } else if( (x1==n1) || (x2==n2) ){ if((x2==n2) && (x1==0)) { ll = 0 } if((x2==n2) && (x1!=0)) { phat1 = x2/n2 phat2 = x1/n1 phihat = phat2/phat1 phil = 0.95*phihat chi2 = 0 while (chi2 <= z){ a = (n2+n1)*phil b = -((x2+n1)*phil+x1+n2) c = x2+x1 p1hat = (-b-sqrt(b^2-4*a*c))/(2*a) p2hat = p1hat*phil q2hat = 1-p2hat var = (n2*n1*p2hat)/(n1*(phil-p2hat)+n2*q2hat) chi2 = ((x1-n1*p2hat)/q2hat)/sqrt(var) ll = phil phil = ll/1.0001}} i = x2 j = x1 ni = n2 nj = n1 if( x1==n1 ){ i = x1 j = x2 ni = n1 nj = n2 } phat1 = i/ni phat2 = j/nj phihat = phat2/phat1 phiu = 1.1*phihat if((x2==n2) && (x1==0)) { if(n2<100) {phiu = .01} else {phiu=0.001} } chi1 = 0 while (chi1 >= -z){ a = (ni+nj)*phiu b = -((i+nj)*phiu+j+ni) c = i+j p1hat = (-b-sqrt(b^2-4*a*c))/(2*a) p2hat = p1hat*phiu q2hat = 1-p2hat var = (ni*nj*p2hat)/(nj*(phiu-p2hat)+ni*q2hat) chi1 = ((j-nj*p2hat)/q2hat)/sqrt(var) phiu1 = phiu phiu = 1.0001*phiu1 } if(x1==n1) { ul = (1-(n1-x1)*(1-p0up)/(x2+n1-(n2+n1)*p0up))/p0up ll = 1/phiu1 } else{ ul = phiu1} } else{ ul = (1-(n1-x1)*(1-p0up)/(x2+n1-(n2+n1)*p0up))/p0up ll = (1-(n1-x1)*(1-p0low)/(x2+n1-(n2+n1)*p0low))/p0low } } c(ll,ul) } # computes the score CI for the relative risk p1/p2 # with success counts x1, x2 and trials n1, n2 # and with confidence coefficient = conflev # written by Yongyi Min -----------------------------------------------------------------------------
R Code for large-sample score confidence interval for an odds ratio in a 2x2 table (Cornfield 1956, Miettinen and Nurminen 1985)
----------------------------------------------------------------------------- orscoreci <- function(x1,n1,x2,n2,conflev){ px = x1/n1 py = x2/n2 if(((x1==0) && (x2==0)) || ((x1==n1) && (x2==n2))){ ul = 1/0 ll = 0 } else if((x1==0) || (x2==n2)){ ll = 0 theta = 0.01/n2 ul = limit(x1,n1,x2,n2,conflev,theta,1) } else if((x1==n1) || (x2==0)){ ul = 1/0 theta = 100*n1 ll = limit(x1,n1,x2,n2,conflev,theta,0) } else{ theta = px/(1-px)/(py/(1-py))/1.1 ll = limit(x1,n1,x2,n2,conflev,theta,0) theta=px/(1-px)/(py/(1-py))*1.1 ul = limit(x1,n1,x2,n2,conflev,theta,1) } c(ll,ul) } limit <- function(x,nx,y,ny,conflev,lim,t){ z = qchisq(conflev,1) px = x/nx score= 0 while ( score < z){ a = ny*(lim-1) b = nx*lim+ny-(x+y)*(lim-1) c = -(x+y) p2d = (-b+sqrt(b^2-4*a*c))/(2*a) p1d = p2d*lim/(1+p2d*(lim-1)) score = ((nx*(px-p1d))^2)*(1/(nx*p1d*(1-p1d))+1/(ny*p2d*(1-p2d))) ci = lim if(t==0) { lim = ci/1.001 } else{ lim = ci*1.001 } } return(ci) } # computes the score CI for the odds ratio p1(1-p2)/(p2(1-p1)) # with success counts x1, x2 and trials n1, n2 # and with confidence coefficient = conflev # written by Yongyi Min -----------------------------------------------------------------------------