如何用R生成变量各区间等量随机样本及问题求助
问题描述
- 随机变量X取值范围为0到1,可服从均匀分布或偏态分布
- 将X划分为5个等距区间:
[0,0.2]、[0.2,0.4]、[0.4,0.6]、[0.6,0.8]、[0.8,1],需要生成100个样本,要求每个区间恰好包含20个样本 - 尝试采用计数法实现,但编写的R代码无法保证每个区间样本数完全一致
原代码问题分析
原代码的核心逻辑错误在于先赋值样本再判断计数器是否超限:当某个区间的计数器已经达到20时,若生成该区间的随机值,代码会先将值存入数组,再判断计数器是否超过20(此时计数器仍为20,会错误地接受该样本),随后计数器加1变为21,导致该区间样本数超标,同时其他区间可能无法凑够20个样本。
解决方案
方法1:均匀分布下的高效实现
如果X服从均匀分布,无需循环过滤,直接在每个区间内生成20个均匀样本即可,效率更高且完全符合要求:
# 定义区间边界 breaks <- seq(0, 1, by = 0.2) x <- numeric(100) # 为每个区间生成20个均匀分布样本 for (i in 1:5) { start <- breaks[i] end <- breaks[i + 1] # 给对应位置赋值 x[(20*(i-1)+1):(20*i)] <- runif(20, min = start, max = end) } # 验证各区间样本数 sim.cut <- cut(x, breaks = breaks, include.lowest = TRUE) table(sim.cut)
方法2:适配偏态分布的通用计数法
如果需要生成偏态分布(如Beta分布)的样本,且严格控制每个区间样本数,修正原代码的逻辑:先判断计数器是否未满,再决定是否接受样本:
x <- numeric(100) # 用向量管理5个区间的计数器,更简洁 cnt <- rep(0, 5) breaks <- seq(0, 1, by = 0.2) for (i in 1:100) { check <- 0 while (check == 0) { # 替换为目标偏态分布,例如rbeta(1, shape1=2, shape2=5) rv <- runif(1) # 确定当前随机值所属区间 interval <- findInterval(rv, breaks) # 修正边界值0的区间归属(findInterval返回0,对应第一个区间) interval <- ifelse(rv == 0, 1, interval) # 只有当该区间样本数不足20时,才接受这个样本 if (cnt[interval] < 20) { x[i] <- rv cnt[interval] <- cnt[interval] + 1 check <- 1 } } } # 验证样本分布 sim.cut <- cut(x, breaks = breaks, include.lowest = TRUE) table(sim.cut)
关键修正说明:
- 使用向量
cnt替代单独的计数器变量,代码更简洁易维护 - 调整逻辑顺序:先检查区间样本数是否未满,再接受样本并更新计数器
- 用
findInterval简化区间判断,避免多层嵌套if语句 - 处理边界值(如
rv=0)的区间归属问题,确保分类准确
内容的提问来源于stack exchange,提问作者Vincent
相关产品推荐
相关产品推荐

