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

如何在R中生成10%数值大于50的500个正态分布样本?

解决R语言模拟指定分布样本的问题

要生成满足要求的样本,我们可以基于截断正态分布分两部分生成,再合并得到近似正态的整体样本,具体步骤如下:

步骤1:确定正态分布参数

我们需要一个基础正态分布,使得:

  • 10%的概率密度落在50以上(匹配50个样本>50的比例)
  • 极少量概率密度落在0以下(保证其余450个样本在0-50区间内)

通过正态分布分位数计算参数:

# 计算对应分位数的Z值
z_90 <- qnorm(0.9)  # P(X ≤ 50) = 0.9 对应的Z值≈1.2816
z_99 <- qnorm(0.99) # P(X > 0) = 0.99 对应的Z值≈2.3263

# 求解均值μ和标准差σ
sigma <- 50 / (z_90 + z_99)
mu <- z_99 * sigma

计算得到:μ≈32.24,σ≈13.86,该分布满足P(X>50)=0.1,且P(X≤0)仅约1%。

步骤2:分两部分生成样本

方法1:使用truncnorm包(高效便捷)

如果未安装包先执行install.packages("truncnorm"):

library(truncnorm)

# 生成50个大于50的样本(截断下限为50)
upper_samples <- rtruncnorm(n = 50, a = 50, b = Inf, mean = mu, sd = sigma)

# 生成450个0到50之间的样本(截断上下限为0和50)
lower_samples <- rtruncnorm(n = 450, a = 0, b = 50, mean = mu, sd = sigma)

# 合并得到最终样本
final_sample <- c(lower_samples, upper_samples)

方法2:手动筛选生成(无依赖)

# 生成50个>50的样本
upper_samples <- numeric(50)
i <- 1
while(i <= 50) {
  x <- rnorm(1, mean = mu, sd = sigma)
  if(x > 50) {
    upper_samples[i] <- x
    i <- i + 1
  }
}

# 生成450个0-50之间的样本
lower_samples <- numeric(450)
i <- 1
while(i <= 450) {
  x <- rnorm(1, mean = mu, sd = sigma)
  if(x > 0 & x <= 50) {
    lower_samples[i] <- x
    i <- i + 1
  }
}

final_sample <- c(lower_samples, upper_samples)

步骤3:验证样本符合要求

# 检查大于50的样本数量
sum(final_sample > 50) # 输出应为50

# 检查是否有样本小于0
sum(final_sample < 0) # 输出应为0

# 可视化分布,验证近似正态性
hist(final_sample, breaks = 20, col = "lightblue", main = "Approximate Normal Sample")
qqnorm(final_sample)
qqline(final_sample)

内容的提问来源于stack exchange,提问作者RamsesII

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 21:20:26