如何在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
相关产品推荐
相关产品推荐

