选择bootstrap样本量:如何用R的boot()抽取7个观测匹配总体加权均值
问题分析
你原有代码的逻辑冲突点在于:boot()默认会自动生成与原数据集等长的重抽样索引i,你既在自定义统计量里手动抽了7条样本,又用boot生成的长索引去二次索引7条的子样本,属于逻辑错误,自然无法得到你要的7条样本的计算结果。
你可以选择两种方案实现需求,优先推荐更灵活的自定义重抽样方案,无需依赖boot包的规则限制。
方案1:自定义重抽样实现(推荐)
# 第一步:先计算全量数据的基准加权均值,作为后续逼近的目标 pop_SAM <- weighted.mean(datamatrix[,3], datamatrix[,1]) pop_CAM <- weighted.mean(datamatrix[,4], datamatrix[,1]) # 如果29个变量都要匹配,可以批量计算所有变量的总体加权均值 # 第二步:定义单次抽样+误差计算函数 sample_7_metric <- function(data, replace = FALSE) { # 无放回抽7条不重复观测,允许重复的话把replace改成TRUE idx <- sample(nrow(data), size = 7, replace = replace) sub_data <- data[idx,] sam <- weighted.mean(sub_data[,3], sub_data[,1]) cam <- weighted.mean(sub_data[,4], sub_data[,1]) # 计算和总体均值的误差,这里用平方和,可根据需求替换为其他误差指标 error <- (sam - pop_SAM)^2 + (cam - pop_CAM)^2 return(list(subset_idx = idx, SAM = sam, CAM = cam, error = error)) } # 第三步:批量跑重抽样,R可根据精度需求调整 set.seed(123) # 设随机种子保证结果可复现 R <- 1000 res_list <- lapply(1:R, function(x) sample_7_metric(datamatrix)) # 第四步:提取误差最小的最优7条观测组合 errors <- sapply(res_list, function(x) x$error) best_res <- res_list[[which.min(errors)]] best_subset <- datamatrix[best_res$subset_idx,]
方案2:适配boot包的实现
如果你坚持要使用boot包,可以修改sim参数跳过默认的等长抽样逻辑,自定义抽样规则:
library(boot) # 提前计算总体基准值 pop_SAM <- weighted.mean(datamatrix[,3], datamatrix[,1]) pop_CAM <- weighted.mean(datamatrix[,4], datamatrix[,1]) # 重写统计量函数,不使用boot自动生成的索引,手动控制抽样 functionWAM <- function(data, p) { idx <- sample(nrow(data), size = p, replace = FALSE) sub_data <- data[idx,] sam <- weighted.mean(sub_data[,3], sub_data[,1]) cam <- weighted.mean(sub_data[,4], sub_data[,1]) error <- (sam - pop_SAM)^2 + (cam - pop_CAM)^2 return(c(SAM = sam, CAM = cam, error = error, subset_idx = idx)) } # 调用boot,指定参数跳过默认抽样逻辑 WAMresults <- boot( data = datamatrix, statistic = functionWAM, R = 1000, sim = "parametric", ran.gen = function(data, ...) data, p = 7 ) # 提取最优结果 best_idx <- which.min(WAMresults$t[,3]) best_subset_idx <- WAMresults$t[best_idx, 4:10] best_subset <- datamatrix[best_subset_idx,]
优化建议
- 如果需要匹配全部29个变量的加权均值,把误差计算逻辑改为所有变量加权均值差的平方和即可
- 对结果精度要求更高的话,可以把重抽样次数R调大到10000,1700行的数据集运算量完全可承受
- 若要求7条观测不可重复,抽样时保持
replace = FALSE即可
内容的提问来源于stack exchange,提问作者User3101
相关产品推荐
相关产品推荐

