df <- read.csv("https://raw.githubusercontent.com/roualdes/data/refs/heads/master/carnivora.csv") df$sf <- df$SuperFamily == "Caniformia" fitl <- glm(sf ~ LY, data = df, family="binomial") predict(fitl, newdata = data.frame(LY = c(100, 101)), type = "response") |> diff() # mean example N <- 100 x <- rnorm(N) meen <- function(data, idx, ...) { mean(data[idx]) } R <- 1001 ms <- rep(NA, R) for (r in 1:R) { idx <- sample(1:N, N, replace = TRUE) ms[r] <- meen(x, idx) } sd(ms) # bootstrapped estimate of standard error sd(x) / sqrt(N) # standard error quantile(ms, c(0.025, 0.975)) # confidence interval for mean # generalize to function bootstrap <- function(data, stat, R = 1001, ...) { if(is.vector(data)) { N <- length(data) } else { N <- nrow(data) } ms <- rep(NA, R) for (r in 1:R) { idx <- sample(1:N, N, replace = TRUE) ms[r] <- stat(data, idx, ...) } return(list(ms = ms, m0 = stat(data, idx, ...))) } b <- bootstrap(x, meen, newdata = 3) b$m0 quantile(b$ms, c(0.025, 0.975)) ## Logistic regression "slope" example logistic_slope <- function(data, idx, newdata = NULL) { fitl <- glm(sf ~ LY, data = data[idx,], family="binomial") diff(predict(fitl, newdata = newdata, type = "response")) } b <- bootstrap(df, logistic_slope, newdata = data.frame(LY = c(200, 201))) quantile(b$ms, c(0.025, 0.975 ))