Ok, here’s my own take on what this function should look like! To test it out, I used the data on mist-netting birds and bats from the “Comparing Sample Proportions: Two Sample Z-Tests” section of Module 10.
Z.prop.test<-function(p1,n1,p2=NULL,n2=NULL,p0,alternative="two.sided",conf.level=0.95)
{
if(is.na(p1))
stop("You must enter a value for 'p1'!")
if(is.na(n1))
stop("You must enter a value for 'n1'!")
if(is.na(p0))
stop("You must enter a value for 'p0'!")
if(!missing(conf.level) &&
(length(conf.level) != 1 || !is.finite(conf.level) ||
conf.level < 0 || conf.level > 1))
stop("'conf.level' must be a single number between 0 and 1")
if(is.null(p2) || is.null(n2)) {
phat1<-p1
pi<-p0
n<-n1
z<-(phat1-pi)/sqrt(pi*((1-pi)/n1))
names(z)<-"Z score"
if(alternative=="two.sided") {
stop("You must choose alternative = 'upper' or 'lower'")}
}
else {
phat1<-p1
phat2<-p2
pi<-p0
n1<-n1
n2<-n2
z<-(phat2-phat1)/sqrt((p0*(1-p0))*(1/n1+1/n2))
names(z)<-"Z score"}
if(alternative=="two.sided"){
p<-1-pnorm(z,lower.tail=TRUE)+pnorm(z,lower.tail=FALSE)
names(p)<-"P-value"
lower<-sqrt(((phat1*(1-phat1))/n1)+((phat2*(1-phat2))/n2))
upper<-pi+qnorm(1-conf.level/2)*sqrt(pi*(1-pi)/n1)
ci<-c(lower,upper)
names(ci)<-"CI"
#crit<-qnorm(conf.level/2)
#test<-p<-crit || p>crit
}
if(alternative=="lower") {
p<-pnorm(z,lower.tail=TRUE)
names(p)<-"P-value"
lower<-phat1-qnorm(1-conf.level/2) * sqrt(phat1 * (1-phat1)/n1)
upper<-phat1+qnorm(1-conf.level/2) * sqrt (phat1 * (1-phat1)/n1)
ci<-c(lower,upper)
names(ci)<-"CI"
#crit<-qnorm(conf.level/2)
#test<-p<-crit || p>crit
}
if(alternative=="upper") {
p<-pnorm(z,lower.tail=FALSE)
names(p)<-"P-value"
lower<-phat1-qnorm(1-conf.level/2)*sqrt(phat1*(1-phat1)/n1)
upper<-phat1+qnorm(1-conf.level/2)*sqrt(phat1*(1-phat1)/n1)
ci<-c(lower,upper)
names(ci)<-"CI"
#crit<-qnorm(conf.level/2)
#test<-p<-crit || p>crit
}
names(p0)<-"p0"
names(p1)<-"p1"
names(n1)<-"n1"
attr(ci,"conf.level") <- conf.level
if(is.null(p2) || is.null(n2)) {
RVAL <- list(method = "One-Sample Z Test of Proportions",
data.name = paste0((p1), " success rate in mist nets"),
null.value = p0,
estimate = p1,
statistic = z,
p.value = as.numeric(p),
conf.int = ci,
alternative = alternative)
class(RVAL) <- "htest"
return(RVAL)}
else {
names(p2)<-"p2"
names(n2)<-"n2"
RVAL <- list(method = "Two-Sample Z Test of Proportions",
data.name = paste0((p1), " lactation rate vs. ", (p2), " lactation rate in bats"),
null.value = p0,
estimate = c(p1,p2),
statistic = z,
p.value = as.numeric(p),
conf.int = ci,
alternative = alternative)
class(RVAL) <- "htest"
return(RVAL)
}
}
Here’s a test of it on the one-sample test example using the mist-netted birds data example:
v1 <- c(0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0,
1, 1, 0, 1, 0, 1, 1)
p1<-mean(v1)
n1<-length(v1)
p0<-0.8
Z.prop.test(p1=p1,n1=n1,p0=p0,alternative='lower')
##
## One-Sample Z Test of Proportions
##
## data: 0.6 success rate in mist nets
## Z score = -2.7386, p-value = 0.003085
## alternative hypothesis: true p0 is 0.8
## 95 percent confidence interval:
## 0.5943913 0.6056087
## sample estimates:
## p1
## 0.6
And here’s a two-sample test example using the mist-netted bats:
v1 <- c(1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0,
1, 0)
v2 <- c(1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0,
0, 1, 1, 0, 1, 1, 1)
p1<-mean(v1)
n1<-length(v1)
p2<-mean(v2)
n2<-length(v2)
p0<-(sum(v1) + sum(v2))/(length(v1) + length(v2))
Z.prop.test(p1=p1,n1=n1,p2=p2,n2=n2,p0=p0)
##
## Two-Sample Z Test of Proportions
##
## data: 0.56 lactation rate vs. 0.7 lactation rate in bats
## Z score = 1.0747, p-value = 0.2825
## alternative hypothesis: true p0 is not equal to 0.6363636
## 95 percent confidence interval:
## 0.1298307 0.6423966
## sample estimates:
## p1 p2
## 0.56 0.70