There are several methods for calculating confidence intervals based on the bootstrap samples (this paper provides explanation and guidance). One very simple method for calculating a 95%-confidence interval is just calculating the empirical 2.5th and 97.5th percentiles of the bootstrap samples (seethis interval is called the bootstrap percentile interval; see code below). The simple percentile interval method is rarely used in practice as there are better methods, such as the bias-corrected and accelerated bootstrap (BCa). BCa intervals adjust for both bias and skewness in the bootstrap distribution.
The biasbias is simply estimated as the difference between the mean of the $n$ stored bootstrap samples and the original estimatesestimate(s).
Let's replicate the example from the website but using our own loop incorporating the ideas I've outlined above (drawing repeadetlyrepeatedly with replacement):
#-----------------------------------------------------------------------------
# Load packages
#-----------------------------------------------------------------------------
require(ggplot2)
require(pscl)
require(MASS)
require(boot)
#-----------------------------------------------------------------------------
# Load data
#-----------------------------------------------------------------------------
zinb <- read.csv("http://www.ats.ucla.edu/stat/data/fish.csv")
zinb <- within(zinb, {
nofish <- factor(nofish)
livebait <- factor(livebait)
camper <- factor(camper)
})
#-----------------------------------------------------------------------------
# Calculate zero-inflated regression
#-----------------------------------------------------------------------------
m1 <- zeroinfl(count ~ child + camper | persons, data = zinb,
dist = "negbin", EM = TRUE)
#-----------------------------------------------------------------------------
# Store the original regression coefficients
#-----------------------------------------------------------------------------
original.estimates <- as.vector(t(do.call(rbind, coef(summary(m1)))[, 1:2]))
#-----------------------------------------------------------------------------
# Set the number of replications
#-----------------------------------------------------------------------------
n.sim <- 2000
#-----------------------------------------------------------------------------
# Set up a matrix to store the results
#-----------------------------------------------------------------------------
store.matrix <- matrix(NA, nrow=n.sim, ncol=12)
#-----------------------------------------------------------------------------
# The loop
#-----------------------------------------------------------------------------
set.seed(123)
for(i in 1:n.sim) {
#-----------------------------------------------------------------------------
# Draw the observations WITH replacement
#-----------------------------------------------------------------------------
data.new <- zinb[sample(1:dim(zinb)[1], dim(zinb)[1], replace=TRUE),]
#-----------------------------------------------------------------------------
# Calculate the model with this "new" data
#-----------------------------------------------------------------------------
m <- zeroinfl(count ~ child + camper | persons,
data = data.new, dist = "negbin",
start = list(count = c(1.3711, -1.5152, 0.879),
zero = c(1.6028, -1.6663)))
#-----------------------------------------------------------------------------
# Store the results
#-----------------------------------------------------------------------------
store.matrix[i, ] <- as.vector(t(do.call(rbind, coef(summary(m)))[, 1:2]))
}
#-----------------------------------------------------------------------------
# Save the means, medians and SDs of the bootstrapped statistics
#-----------------------------------------------------------------------------
boot.means <- colMeans(store.matrix, na.rm=T)
boot.medians <- apply(store.matrix,2,median, na.rm=T)
boot.sds <- apply(store.matrix,2,sd, na.rm=T)
#-----------------------------------------------------------------------------
# The bootstrap bias is the difference between the mean bootstrap estimates
# and the original estimates
#-----------------------------------------------------------------------------
boot.bias <- colMeans(store.matrix, na.rm=T) - original.estimates
#-----------------------------------------------------------------------------
# QuantileBasic confidencebootstrap intervalsCIs based on the empirical quantiles
#-----------------------------------------------------------------------------
conf.mat <- matrix(apply(store.matrix, 2 ,quantile, c(0.025, 0.975), na.rm=T),
ncol=2, byrow=TRUE)
colnames(conf.mat) <- c("95%-CI Lower", "95%-CI Upper")
#-----------------------------------------------------------------------------
# Set up summary data frame
#-----------------------------------------------------------------------------
summary.frame <- data.frame(mean=boot.means, median=boot.medians,
sd=boot.sds, bias=boot.bias, "CI_lower"=conf.mat[,1], "CI_upper"=conf.mat[,2])
summary.frame
mean median sd bias CI_lower CI_upper
1 1.29979032998 1.30130793013 0.3967380439674 -0.07129122500712912 0.5196003151960 -1 2.30663510605
2 0.25266882527 0.24857212486 0.0320779003208 -0.00344605090034461 20.0604901519898 - 0.43797613229
3 -1.56616865662 -1.55719895572 0.2622001326220 -0.0509238534 0509239 0-2.1989775912900 0-1.14493540920
4 0.20049572005 0.19864541986 0.0194943701949 0.00490189550049019 0.3229413016744 0.21401182418
5 0.95438349544 0.92520359252 0.4891452348915 0.07534051520753405 -2 0.1289978303493 0 1.44149579025
6 0.27023612702 0.26880952688 0.0204250402043 0.00095825920009583 -1 0.0919599823272 8 0.04711433137
7 -0.89968368997 -0.90823799082 0.2217392122174 0.0856792712 0856793 0-1.1674419830664 -0.58113944380
8 0.17889341789 0.17811611781 0.0166725001667 0.00295125650029513 0.2417977814494 57 0.64166802140
9 2.06826180683 1.77189037719 1.5910232259102 0.46548978654654898 0.0349261244150 - 8.43440380471
10 4.02087570209 0.82697758270 13.2343353923434 3.18457096801845710 10.9024510858114 -1 57.11561276417
11 -2.09694050969 -1.67171026717 1.5631076256311 -0.4306843771 4306844 0-8.2327156643440 0-1.33631011156
12 3.86603458660 0.64348596435 13.2752503327525 3.18706419411870642 0.3137059333631 57.60619936062
#-----------------------------------------------------------------------------
# Compare with boot output and confidence intervals
#-----------------------------------------------------------------------------
set.seed(10)
res <- boot(zinb, f, R = 2000, parallel = "snow", ncpus = 4)
res
Bootstrap Statistics :
original bias std. error
t1* 1.3710504 -0.076735010 0.39842905
t2* 0.2561136 -0.003127401 0.03172301
t3* -1.5152609 -0.064110745 0.26554358
t4* 0.1955916 0.005819378 0.01933571
t5* 0.8790522 0.083866901 0.49476780
t6* 0.2692734 0.001475496 0.01957823
t7* -0.9853566 0.083186595 0.22384444
t8* 0.1759504 0.002507872 0.01648298
t9* 1.6031354 0.482973831 1.58603356
t10* 0.8365225 3.240981223 13.86307093
t11* -1.6665917 -0.453059768 1.55143344
t12* 0.6793077 3.247826469 13.90167954
perc.cis <- matrix(NA, nrow=dim(res$t)[2], ncol=2)
for( i in 1:dim(res$t)[2] ) {
perc.cis[i,] <- boot.ci(res, conf=0.95, type="perc", index=i)$percent[4:5]
}
colnames(perc.cis) <- c("95%-CI Lower", "95%-CI Upper")
perc.cis
95%-CI Lower 95%-CI Upper
[1,] 0.52240 2.1035
[2,] 0.19984 0.3220
[3,] -2.12820 -1.1012
[4,] 0.16754 0.2430
[5,] 0.04817 1.9084
[6,] 0.23401 0.3124
[7,] -1.29964 -0.4314
[8,] 0.14517 0.2149
[9,] 0.29993 8.0463
[10,] 0.57248 56.6710
[11,] -8.64798 -1.1088
[12,] 0.33048 56.6702
#-----------------------------------------------------------------------------
# Our summary table
#-----------------------------------------------------------------------------
summary.frame
mean median sd bias CI_lower CI_upper
1 1.29979032998 1.30130793013 0.3967380439674 -0.07129122500712912 0.5196003151960 -1 2.30663510605
2 0.25266882527 0.24857212486 0.0320779003208 -0.00344605090034461 20.0604901519898 - 0.43797613229
3 -1.56616865662 -1.55719895572 0.2622001326220 -0.0509238534 0509239 0-2.1989775912900 0-1.14493540920
4 0.20049572005 0.19864541986 0.0194943701949 0.00490189550049019 0.3229413016744 0.21401182418
5 0.95438349544 0.92520359252 0.4891452348915 0.07534051520753405 -2 0.1289978303493 0 1.44149579025
6 0.27023612702 0.26880952688 0.0204250402043 0.00095825920009583 -1 0.0919599823272 8 0.04711433137
7 -0.89968368997 -0.90823799082 0.2217392122174 0.0856792712 0856793 0-1.1674419830664 -0.58113944380
8 0.17889341789 0.17811611781 0.0166725001667 0.00295125650029513 0.2417977814494 57 0.64166802140
9 2.06826180683 1.77189037719 1.5910232259102 0.46548978654654898 0.0349261244150 - 8.43440380471
10 4.02087570209 0.82697758270 13.2343353923434 3.18457096801845710 10.9024510858114 -1 57.11561276417
11 -2.09694050969 -1.67171026717 1.5631076256311 -0.4306843771 4306844 0-8.2327156643440 0-1.33631011156
12 3.86603458660 0.64348596435 13.2752503327525 3.18706419411870642 0.3137059333631 57.60619936062
Compare the "bias" columns and the "std. error" with the "sd" column of our own summary table. Our 95%-confidence intervals are very similar to the confidence intervals calculated by boot.ci
using the percentile method (not all though: look at the lower limit of parameter with index 9).