如何在R中按预设比例生成1000组5元素无重复抽样样本?
问题:如何在R中生成符合指定元素出现比例的无重复抽样样本
现有样本数据:
test <- c("a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q", "r","s","t","u","v","w","x","y","z")
需要生成1000组样本,每组包含5个唯一元素,且每个元素在所有样本中的总出现次数符合指定比例(例如"a"需约出现900次)。尝试以下代码后,元素出现比例未达预期(如"a"的出现比例远低于预期):
sample_function <- function(){sample(test,5,replace = FALSE, prob = c('0.9', '0.8','0.45','0.6','0.3','0.05','0.08','0.12','0.79','0.33','0.24','0.1','0.1', '0.76','0.22','0.2','0.7','0.67','0.35','0.45','0.07','0.11','0.14','0.03','0.02', '0.05')) } sample_data <- replicate(1000,sample_function()) sum(sample_data=="a")
原代码问题分析
prob参数传入字符串类型数值虽会被R自动转换,但核心问题是:当replace=FALSE时,sample的prob是元素被选中的相对权重,而非绝对概率。- 无重复抽样限制了每个元素在单组中最多出现1次,直接用这种方式无法保证总出现次数接近目标比例(比如"a"要出现900次,意味着要进入90%的组)。
解决方案:基于目标次数的精准抽样
方法1:预构造元素池分割法
先按目标次数生成元素池,打乱后分割为1000组,确保总出现次数完全符合要求,同时避免组内重复。
# 1. 定义各元素目标出现次数(总次数需等于1000*5=5000) target_counts <- c( a=900, b=800, c=450, d=600, e=300, f=50, g=80, h=120, i=790, j=330, k=240, l=100, m=100, n=760, o=220, p=200, q=700, r=670, s=350, t=450, u=70, v=110, w=140, x=30, y=20, z=50 ) test <- names(target_counts) # 2. 生成包含目标次数的元素池 element_pool <- rep(test, times = target_counts) # 3. 打乱池并分割为1000组(每组5个) set.seed(123) # 设置随机种子保证结果可复现 element_pool <- sample(element_pool) sample_data <- matrix(element_pool, ncol=1000, byrow=FALSE) # 检查组内是否有重复(若目标次数分配合理,此情况极少) any(apply(sample_data, 2, function(x) length(unique(x)) <5)) # 验证各元素总出现次数 table(c(sample_data))
方法2:迭代抽样法(更灵活)
通过迭代逐组抽样,每次更新剩余可使用的元素次数,确保每组无重复且总次数精准达标。
set.seed(123) sample_data <- matrix(NA, nrow=5, ncol=1000) remaining_counts <- target_counts for(col in 1:1000){ # 从剩余次数>0的元素中抽5个无重复样本 available_elements <- test[remaining_counts > 0] sampled <- sample(available_elements, 5, replace=FALSE) sample_data[,col] <- sampled # 扣除已使用的元素次数 remaining_counts[sampled] <- remaining_counts[sampled] -1 } # 验证结果 table(c(sample_data))
内容的提问来源于stack exchange,提问作者user17589146
相关产品推荐
相关产品推荐

