You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 03:00:08