在R中模拟获取真实标准差所需样本量并复现对应可视化图表

你现有代码的核心问题是不同样本量对应的总体标准差不统一,你给rnorm传入的第三个参数逐次变小,所以你得到的曲线是总体标准差本身下降的结果,和“样本量增大时样本标准差收敛到真实总体标准差”的仿真目标不符。
正确实现思路
- 固定总体分布参数:比如设定正态分布均值为0、真实标准差为固定值,若使用t分布可先计算对应自由度下的真实标准差,按需调整缩放系数。
- 设定测试用的样本量序列,覆盖你需要观测的收敛区间。
- 每个样本量可重复抽样多次取平均,消除随机波动,让收敛曲线更平滑;如果需要展示波动范围,可保留多次抽样的分位数结果。
- 绘图时添加真实标准差的参考线,方便对比收敛效果。
代码实现
基础版:正态分布收敛曲线
set.seed(123) # 仿真参数设置 true_sd <- 10 # 设定真实总体标准差 sample_sizes <- seq(1, 200, by = 1) # 测试的样本量范围 n_rep <- 100 # 每个样本量重复抽样次数,数值越大曲线越平滑 # 计算每个样本量对应的平均样本标准差 sd_result <- sapply(sample_sizes, function(n) { replicate(n_rep, sd(rnorm(n, mean = 0, sd = true_sd))) |> mean() }) # 绘制结果 plot(sample_sizes, sd_result, type = "l", lwd = 2, col = "darkblue", xlab = "样本量", ylab = "样本标准差", main = "正态分布下样本标准差随样本量收敛情况") # 添加真实标准差参考线 abline(h = true_sd, col = "red", lwd = 2, lty = 2) legend("bottomright", legend = c("样本标准差均值", "真实总体标准差"), col = c("darkblue", "red"), lty = c(1,2), lwd = 2)
t分布版本
仅需要修改抽样部分的代码,调整为t分布并做缩放匹配目标真实标准差即可:
set.seed(123) df <- 5 # t分布自由度 target_true_sd <- 10 # 目标真实标准差 # t分布原始标准差为sqrt(df/(df-2)),计算缩放系数匹配目标标准差 scale_factor <- target_true_sd / sqrt(df/(df-2)) sample_sizes <- seq(1, 200, by = 1) n_rep <- 100 sd_result_t <- sapply(sample_sizes, function(n) { replicate(n_rep, sd(scale_factor * rt(n, df = df))) |> mean() }) plot(sample_sizes, sd_result_t, type = "l", lwd = 2, col = "darkgreen", xlab = "样本量", ylab = "样本标准差", main = "t分布下样本标准差随样本量收敛情况") abline(h = target_true_sd, col = "red", lwd = 2, lty = 2) legend("bottomright", legend = c("样本标准差均值", "真实总体标准差"), col = c("darkgreen", "red"), lty = c(1,2), lwd = 2)
带波动区间的版本
如果需要复现原图中可能存在的波动范围,可绘制多次抽样的95%分位数区间:
set.seed(123) true_sd <- 10 sample_sizes <- seq(1, 200, by = 1) n_rep <- 100 # 保留所有重复抽样的结果 sd_all <- sapply(sample_sizes, function(n) { replicate(n_rep, sd(rnorm(n, mean = 0, sd = true_sd))) }) # 计算均值和95%分位区间 sd_mean <- apply(sd_all, 2, mean) sd_q025 <- apply(sd_all, 2, quantile, 0.025) sd_q975 <- apply(sd_all, 2, quantile, 0.975) # 绘图 plot(sample_sizes, sd_mean, type = "l", lwd = 2, col = "darkblue", ylim = range(c(sd_q025, sd_q975)), xlab = "样本量", ylab = "样本标准差", main = "样本标准差收敛(含95%波动区间)") # 绘制区间填充 polygon(c(sample_sizes, rev(sample_sizes)), c(sd_q025, rev(sd_q975)), col = adjustcolor("lightblue", 0.3), border = NA) abline(h = true_sd, col = "red", lwd = 2, lty = 2) legend("bottomright", legend = c("样本标准差均值", "95%波动区间", "真实总体标准差"), col = c("darkblue", "lightblue", "red"), lty = c(1,NA,2), lwd = c(2,NA,2), pch = c(NA,15,NA))
内容的提问来源于stack exchange,提问作者Homer Jay Simpson
相关产品推荐
相关产品推荐

