在R语言中生成指定范围、指定均值的100个随机小数
生成指定范围与精确均值的随机小数解决方案
需求与问题
- 需求:生成100个范围在10到50之间、均值精确为32.2的随机小数
- 现有方法的局限:
runif(100, min=10, max=50):能满足范围要求,但无法保证均值为32.2rnorm(100, mean=32.2, sd=10):能保证均值,但数值可能超出10-50的范围
- 尝试过的方案:使用
rgbeta函数生成,但均值无法精确到32.2;降低方差后均值接近,但缺少接近10或50的边界数值
解决方案
方法一:基于均匀分布的均值调整(保留边界数值)
先生成指定范围的均匀随机数,再通过调整保证精确均值,同时处理超出范围的数值,确保边界值存在:
n <- 100 min_val <- 10 max_val <- 50 target_mean <- 32.2 # 生成初始均匀分布随机数(set.seed可选,保证结果可复现) set.seed(123) y <- runif(n, min = min_val, max = max_val) # 计算均值调整量 current_mean <- mean(y) adjustment <- target_mean - current_mean # 初步调整所有数值 y_adjusted <- y + adjustment # 修正超出范围的数值,保持总和(均值)不变 below_min <- y_adjusted < min_val above_max <- y_adjusted > max_val while(any(below_min) || any(above_max)) { # 处理低于最小值的情况 if(any(below_min)) { deficit <- min_val - y_adjusted[below_min] y_adjusted[below_min] <- min_val # 将缺口分配到未超出范围的数值上 available <- !below_min & !above_max if(any(available)) { y_adjusted[available] <- y_adjusted[available] + sample(deficit, sum(available), replace = TRUE) } } # 处理高于最大值的情况 if(any(above_max)) { surplus <- y_adjusted[above_max] - max_val y_adjusted[above_max] <- max_val # 将盈余从超出范围的数值转移到未超出的数值上 available <- !below_min & !above_max if(any(available)) { y_adjusted[available] <- y_adjusted[available] - sample(surplus, sum(available), replace = TRUE) } } # 更新状态,循环直到所有数值都在范围内 below_min <- y_adjusted < min_val above_max <- y_adjusted > max_val } # 验证结果 cat("均值:", mean(y_adjusted), "\n") cat("最小值:", min(y_adjusted), "\n") cat("最大值:", max(y_adjusted), "\n")
方法二:截断正态分布+均值调整(兼顾分布形态)
如果需要数值更集中在均值附近的分布形态,可以先生成截断正态分布的数,再调整到精确均值:
library(truncnorm) n <- 100 min_val <- 10 max_val <- 50 target_mean <- 32.2 # 生成初始截断正态分布随机数 set.seed(123) y <- rtruncnorm(n, a = min_val, b = max_val, mean = target_mean, sd = 8) # 调整均值到精确值 current_mean <- mean(y) adjustment <- target_mean - current_mean y_adjusted <- y + adjustment # 修正超出范围的数值,逻辑同方法一 below_min <- y_adjusted < min_val above_max <- y_adjusted > max_val while(any(below_min) || any(above_max)) { if(any(below_min)) { deficit <- min_val - y_adjusted[below_min] y_adjusted[below_min] <- min_val available <- !below_min & !above_max if(any(available)) { y_adjusted[available] <- y_adjusted[available] + sample(deficit, sum(available), replace = TRUE) } } if(any(above_max)) { surplus <- y_adjusted[above_max] - max_val y_adjusted[above_max] <- max_val available <- !below_min & !above_max if(any(available)) { y_adjusted[available] <- y_adjusted[available] - sample(surplus, sum(available), replace = TRUE) } } below_min <- y_adjusted < min_val above_max <- y_adjusted > max_val } # 验证结果 cat("均值:", mean(y_adjusted), "\n") cat("最小值:", min(y_adjusted), "\n") cat("最大值:", max(y_adjusted), "\n")
说明
- 两种方法都能保证均值精确为32.2,同时保留接近10或50的边界数值
- 方法一的数值分布更均匀,方法二的数值更集中在均值附近,可根据需求选择
内容的提问来源于stack exchange,提问作者dlwhch
相关产品推荐
相关产品推荐

