R语言实现数据集多次子采样并确保所有行至少被选中一次
解决数据集全覆盖多次子采样问题的R实现
实现思路
- 核心逻辑:每次采样后,记录未被选中的行,后续优先从这些未选中的行中抽取,直到所有行都被覆盖
- 步骤:
- 初始化一个标记向量,记录每行是否被选中过
- 循环进行采样:
- 先筛选出未被选中的行,若未被选中的行数量≤800,则将这些行全部纳入本次采样,剩余的采样名额从已选中的行中随机补充
- 若未被选中的行数量>800,则直接从未被选中的行中随机抽取800行
- 更新标记向量,检查是否所有行都已被选中,若已全部覆盖则停止循环
R代码实现
# 模拟1000行数据集(实际使用时替换为你的数据集) set.seed(123) # 设置随机种子保证结果可复现 dataset <- data.frame(matrix(rnorm(1000*5), nrow = 1000)) rownames(dataset) <- paste0("Row", 1:1000) # 初始化参数 total_rows <- nrow(dataset) sample_size <- floor(0.8 * total_rows) # 800行 selected_flag <- rep(FALSE, total_rows) # 标记每行是否被选中过 subsamples_list <- list() # 存储所有子样本 # 循环采样直到所有行都被选中 while(!all(selected_flag)){ # 获取未被选中的行索引 unselected_idx <- which(!selected_flag) unselected_count <- length(unselected_idx) if(unselected_count <= sample_size){ # 未选中行不足800,全部纳入,剩下的从已选中行里补 current_sample_idx <- c(unselected_idx, sample(which(selected_flag), size = sample_size - unselected_count)) } else { # 未选中行超过800,直接从中抽取800行 current_sample_idx <- sample(unselected_idx, size = sample_size) } # 更新选中标记 selected_flag[current_sample_idx] <- TRUE # 提取子样本并存入列表 subsamples_list[[length(subsamples_list)+1]] <- dataset[current_sample_idx, ] } # 查看采样次数 cat("总共进行了", length(subsamples_list), "次子采样\n") # 验证所有行是否都被选中 cat("是否所有行都被选中:", all(selected_flag), "\n")
代码说明
set.seed(123):设置随机种子,让采样结果可重复selected_flag:布尔向量,全程跟踪每行的选中状态,确保不会遗漏任何行- 循环终止条件
!all(selected_flag):只要还有未被选中的行,就继续采样 - 两种采样分支:根据未选中行的数量动态调整采样策略,优先覆盖未选中的行,保证最快实现全覆盖
额外说明
- 如果需要控制最大采样次数,可以在循环中加入次数限制(比如
while(!all(selected_flag) && length(subsamples_list) < 10)),避免极端情况下的无限循环 - 实际使用时,将
dataset替换为你的真实数据集即可
内容的提问来源于stack exchange,提问作者Nmgh
相关产品推荐
相关产品推荐

