R: R 概率分布
最后更新:2026-08-26
上一课我们学了"看数据"——描述统计。这一课学"看随机性"——概率分布。所有 R 统计推断(t 检验、回归、假设检验)都建立在概率分布上。这一课我们学 R 的
d/p/q/r四大函数族 + 4 大常用分布。
读完这一课你就能用 R 模拟任何随机现象、做概率计算、为后续假设检验打基础。
1. 你将学到
- 概率分布 4 大函数族(d/p/q/r)
- 正态分布(最常用)
- 二项分布(成功/失败)
- 泊松分布(事件计数)
- t 分布 / F 分布 / 卡方分布
- set.seed 随机种子
- 实战:质量检测模拟
2. 一个质量检测的故事
(1) 痛点:产品合格率多少正常?
Alice是质检员,发现某生产线产品重量均值 100g,标准差 2g。manager问:"重量 < 95g 的比例是多少?"
翻书查正态分布表?Excel 公式?R 一行——
(2) R 的解法
# 重量 < 95g 的概率
pnorm(95, mean = 100, sd = 2)
# [1] 0.00621 ← 0.6%
# 抽取 1000 个产品模拟检测
set.seed(42)
samples <- rnorm(1000, mean = 100, sd = 2)
mean(samples < 95) # 0.6% ← 验证
2 行代码 → 答案 + 模拟验证。
3. R 概率分布的 4 大函数族
(1) 4 大函数对比
| 函数前缀 | 含义 | 用途 |
|---|---|---|
d |
density(密度) | 概率密度 PDF |
p |
probability(概率) | 累积概率 CDF |
q |
quantile(分位数) | 反函数(已知概率求分位) |
r |
random(随机) | 生成随机数 |
所有分布都有这 4 个函数:dnorm pnorm qnorm rnorm(正态);dbinom pbinom...(二项)等。
(2) 速记口诀
graph LR
A[d 密度] -->|求概率| B[p 累积]
B -->|反求分位| C[q 分位]
A -->|模拟| D[r 随机]
style A fill:#cce5ff
style B fill:#d4edda
style C fill:#f8d7da
style D fill:#fff3cd
(3) 4 大函数详解
# 以正态分布为例(均值 0,标准差 1)
dnorm(0) # 0.3989 ← 概率密度
pnorm(0) # 0.5 ← 累积概率
qnorm(0.975) # 1.96 ← 已知 97.5% 求分位
rnorm(5) # 5 个随机数
# 自定义参数(均值 100,标准差 2)
dnorm(95, 100, 2) # 95 处的密度
pnorm(95, 100, 2) # 95 左侧累积概率
qnorm(0.975, 100, 2) # 已知 97.5% 求分位
rnorm(5, 100, 2) # 5 个均值 100 随机数
4. 正态分布(最常用)
(1) 什么是正态分布?
graph TB
A[正态分布 N mu sigma] --> B[钟形对称]
A --> C[68-95-99.7 法则]
A --> D[中心极限定理]
A --> E[广泛存在于自然/社会现象]
style A fill:#fff3cd
style B fill:#cce5ff
style C fill:#d4edda
style D fill:#f8d7da
style E fill:#e1d4ff
正态分布 = 钟形、对称、自然界最常见的分布。
(2) 68-95-99.7 法则
μ ± 1σ → 68.27% 数据
μ ± 2σ → 95.45% 数据
μ ± 3σ → 99.73% 数据
(3) 4 大正态函数
# 标准正态 N(0, 1)
dnorm(0) # 0.3989
pnorm(1.96) # 0.975 ← 1.96 左侧 97.5%
qnorm(0.975) # 1.96 ← 97.5% 分位 = 1.96
rnorm(5) # 5 个标准正态随机数
# 一般正态 N(μ, σ)
mu <- 100
sigma <- 2
# P(X < 95) = ?
pnorm(95, mean = mu, sd = sigma) # 0.00621
# P(95 < X < 105) = ?
pnorm(105, mu, sigma) - pnorm(95, mu, sigma) # 0.9876
# 99% 数据的范围
qnorm(0.005, mu, sigma) # 下界
qnorm(0.995, mu, sigma) # 上界
(4) 正态性检验
# 1. 视觉:QQ 图
qqnorm(x)
qqline(x, col = "red")
# 2. 统计检验
shapiro.test(x) # Shapiro-Wilk(n < 5000)
# p < 0.05 表示非正态
5. 二项分布(成功/失败)
(1) 什么是二项分布?
n 次独立伯努利试验中成功次数的分布。每次成功概率 p,失败 1-p。
例:抛 10 次硬币,正面朝上的次数 X ~ Binomial(10, 0.5)
(2) 4 大二项函数
# 抛 10 次硬币,正面次数
dbinom(5, size = 10, prob = 0.5) # 0.246 ← P(5 次正面)
pbinom(5, size = 10, prob = 0.5) # 0.623 ← P(≤ 5 次)
qbinom(0.5, size = 10, prob = 0.5) # 5 ← 中位数
rbinom(1000, size = 10, prob = 0.5) # 1000 个 10 次试验的正面次数
# 例:100 发子弹,命中率 80%,至少命中 90 发的概率
1 - pbinom(89, size = 100, prob = 0.8)
# [1] 0.0227 ← 2.3%
(3) 二项可视化
n <- 10
p <- 0.5
x <- 0:n
# 概率质量函数
plot(x, dbinom(x, n, p), type = "h",
main = paste0("Binomial(", n, ",", p, ")"),
xlab = "成功次数", ylab = "概率",
col = "blue", lwd = 2)
points(x, dbinom(x, n, p), pch = 19, col = "red")
6. 泊松分布(事件计数)
(1) 什么是泊松分布?
固定时间/空间内事件发生次数的分布。常用于:
- 1 小时内到店客户数
- 1 公里道路上的车祸数
- 1 天内接到的电话数
参数 λ = 单位时间平均事件数。
(2) 4 大泊松函数
# 例:1 小时平均到店 10 个客户
dpois(8, lambda = 10) # P(X = 8) = 0.1126
ppois(8, lambda = 10) # P(X ≤ 8) = 0.3328
qpois(0.5, lambda = 10) # 中位数 = 10
rpois(100, lambda = 10) # 100 个小时到店客户数
# 例:1 天接 5 个投诉,超过 10 个的概率
1 - ppois(10, lambda = 5) # 0.0137 ← 1.4%
(3) 泊松与正态关系
当 λ 大时,泊松近似正态 N(λ, √λ):
# λ = 100
lambda <- 100
# 泊松 P(90 ≤ X ≤ 110)
ppois(110, lambda) - ppois(89, lambda) # ≈ 0.728
# 等价正态近似
pnorm(110, 100, 10) - pnorm(90, 100, 10) # ≈ 0.683
# 近似但不完全相等
7. t 分布 / F 分布 / 卡方分布
(1) 三大抽样分布速查
| 分布 | 用途 | R 函数 |
|---|---|---|
| t 分布 | 小样本均值推断 | dt/pt/qt/rt |
| F 分布 | 方差比较(ANOVA) | df/pf/qf/rf |
| 卡方分布 | 分类变量、拟合优度 | dchisq/pchisq/qchisq/rchisq |
(2) t 分布详解
# 自由度 df = 10
qt(0.975, df = 10) # 2.228 ← t 临界值(比正态 1.96 更大)
pt(2.228, df = 10) # 0.975
# 当 df → ∞ 时,t 分布 → 标准正态
qt(0.975, df = 1000) # 1.962 ← 接近 1.96
qt(0.975, df = 10000) # 1.960
(3) 卡方分布
# 自由度 df = 5
dchisq(3, df = 5) # 密度
pchisq(11.07, df = 5) # 0.95 ← 卡方临界值(95%)
qchisq(0.95, df = 5) # 11.07
# 例:观测 8 个事件,期望 5,p 值
1 - pchisq(8, df = 5) # 0.846
(4) F 分布
# 自由度 df1 = 5, df2 = 10
qf(0.95, df1 = 5, df2 = 10) # 3.326 ← F 临界值
pf(3.326, df1 = 5, df2 = 10) # 0.95
8. set.seed 随机种子
(1) 为什么需要种子?
R 的"随机数"其实是伪随机——给定种子,结果可重现:
# 不设种子
rnorm(3) # 每次结果不同
# 设种子
set.seed(42)
rnorm(3) # 第一次
set.seed(42)
rnorm(3) # 完全相同
set.seed()——让结果可重现。
(2) 实战用法
# 1. 模拟前设种子
set.seed(42)
sim_data <- rnorm(1000, 100, 15)
# 2. 模型训练前设种子
set.seed(123)
model <- lm(y ~ x, data)
# 3. 交叉验证前设种子
set.seed(2024)
folds <- createFolds(data$y, k = 5)
9. 抽样与模拟
(1) sample() 抽样
# 1. 简单随机抽样
sample(1:100, 10) # 从 1-100 抽 10 个(不重复)
sample(1:100, 10, replace = TRUE) # 放回抽样
# 2. 数据框抽样
sample_n(df, 10) # 抽 10 行(旧)
slice_sample(df, n = 10) # 抽 10 行(dplyr 1.0+)
# 3. 分层抽样
df |>
group_by(class) |>
slice_sample(n = 5) # 每组抽 5 行
# 4. 设置概率抽样
sample(c("A", "B", "C"), 100, replace = TRUE,
prob = c(0.5, 0.3, 0.2))
(2) 蒙特卡洛模拟
# 例:估计 π
set.seed(42)
n_sim <- 100000
x <- runif(n_sim, -1, 1)
y <- runif(n_sim, -1, 1)
inside <- sqrt(x^2 + y^2) <= 1
pi_est <- 4 * mean(inside)
# [1] 3.14116 ← 接近 π = 3.14159
10. 完整示例:质量检测模拟
下面是一个完整工作流示例,把本课所有概率分布知识串起来。
▶ 示例:生产线质量检测模拟
# ============================================
# 生产线质量检测模拟
# 功能:4 种分布综合应用
# ============================================
set.seed(42)
# 1. 产品重量检测(正态分布)
# 规格:均值 100g,标准差 2g
n_products <- 10000
weights <- rnorm(n_products, mean = 100, sd = 2)
cat("=== 重量检测(正态分布 N(100, 2))===\n")
cat("样本数:", length(weights), "\n")
cat("实际均值:", round(mean(weights), 4), "\n")
cat("实际标准差:", round(sd(weights), 4), "\n")
cat("理论 < 95g 比例:", round(pnorm(95, 100, 2), 4), "\n")
cat("实际 < 95g 比例:", round(mean(weights < 95), 4), "\n")
cat("理论 < 105g 比例:", round(pnorm(105, 100, 2), 4), "\n")
cat("实际 < 105g 比例:", round(mean(weights < 105), 4), "\n\n")
# 2. 不合格品检测(二项分布)
# 抽样 100 个,至少 95 个合格的概率
n_sample <- 100
p_pass <- 0.95
prob_at_least_95 <- 1 - pbinom(94, n_sample, p_pass)
cat("=== 抽样检测(Binomial(100, 0.95))===\n")
cat("P(95 个合格) =", round(prob_at_least_95, 4), "\n\n")
# 3. 客户到店(泊松分布)
# 1 小时平均 10 个客户
n_hours <- 1000
customers <- rpois(n_hours, lambda = 10)
cat("=== 客户到店(Poisson(10))===\n")
cat("理论均值:10\n")
cat("实际均值:", round(mean(customers), 2), "\n")
cat("理论 P(>15):", round(1 - ppois(15, 10), 4), "\n")
cat("实际 P(>15):", round(mean(customers > 15), 4), "\n\n")
# 4. 抽样调查(t 分布)
# 抽 30 个产品,估计均值
sample_size <- 30
sample_data <- sample(weights, sample_size)
cat("=== 抽样调查(t 分布)===\n")
cat("样本量:", sample_size, "\n")
cat("样本均值:", round(mean(sample_data), 2), "\n")
cat("95% 置信区间:[\n")
ci <- t.test(sample_data)$conf.int
cat(" ", round(ci[1], 2), ",", round(ci[2], 2), "]\n\n")
# 5. 假设检验(用 qnorm)
# 想知道重量是否显著偏离 100g
z_score <- (mean(sample_data) - 100) / (sd(sample_data) / sqrt(sample_size))
p_value <- 2 * (1 - pnorm(abs(z_score)))
cat("=== 假设检验(Z 检验)===\n")
cat("Z 分数:", round(z_score, 4), "\n")
cat("P 值:", round(p_value, 4), "\n")
cat("结论:", ifelse(p_value < 0.05, "显著偏离 100g", "无显著差异"), "\n\n")
# 6. 异常值检测(卡方分布概念)
# 用 3σ 法则
outliers <- weights[abs(weights - 100) > 3 * 2]
cat("=== 异常值检测(3σ 法则)===\n")
cat("理论异常比例:", round(2 * pnorm(-3), 6), "(即 0.27%)\n")
cat("实际异常数:", length(outliers), "/", n_products, "\n")
cat("实际异常比例:", round(length(outliers) / n_products, 6), "\n")
# 7. 抽样设计(分层抽样)
cat("\n=== 分层抽样 ===\n")
# 模拟 3 条生产线(不同合格率)
production <- tibble::tibble(
line = rep(c("A线", "B线", "C线"), each = 1000),
weight = c(rnorm(1000, 100, 2),
rnorm(1000, 101, 2),
rnorm(1000, 99, 2))
)
# 每条线抽 50 个
library(dplyr)
sampled <- production |>
group_by(line) |>
slice_sample(n = 50)
cat("每线抽 50 个,估算总均值:\n")
cat("总样本均值:", round(mean(sampled$weight), 2), "\n")
cat("总真实均值:", round(mean(production$weight), 2), "\n")
预期输出(节选):
=== 重量检测(正态分布 N(100, 2))===
样本数: 10000
实际均值: 99.9898
实际标准差: 1.9973
理论 < 95g 比例: 0.0062
实际 < 95g 比例: 0.0063
=== 抽样检测(Binomial(100, 0.95))===
P(95 个合格) = 0.5647
❓ 常见问题
📖 小节
- R 概率分布 4 大函数族:
d密度 /p累积 /q分位 /r随机 - 正态分布(最常用):钟形对称、68-95-99.7 法则、
pnorm/qnorm/rnorm - 二项分布:n 次独立试验成功次数,
dbinom/pbinom/qbinom/rbinom - 泊松分布:单位时间事件数,
dpois/ppois/qpois/rpois - t 分布:小样本均值推断(n < 30);F 分布:方差比;卡方分布:分类数据
set.seed(42)让随机可重现——研究报告必加- 抽样:
sample(x, n)不放回 /replace = TRUE放回 - 蒙特卡洛模拟 = 用 r 大量生成 + 统计 估算复杂概率
📝 作业
-
基础题:用
pnorm计算 N(100, 2) 分布中,① P(X < 95) ② P(X > 105) ③ P(95 < X < 105) ④ 99% 置信区间。验证结果。 -
基础题:用
rbinom(1000, 10, 0.5)模拟 1000 次"抛 10 次硬币正面次数",计算样本的 mean、var、sd,对比理论值(5、2.5、1.58)。 -
基础题:用
rpois(1000, 5)模拟 1000 个"5 分钟内接到的电话数",画直方图 + 理论泊松 PDF,对比分布。 -
进阶题:模拟 10000 个产品重量(正态 N(100, 2)),用 3σ 法则识别异常值数量,与理论 0.27% 对比,验证 CLT。
-
挑战题:用蒙特卡洛模拟估算 π:① 投点 10000 次 ② 计算落在 1/4 圆内的比例 ③ 4× 比例 = π 估算 ④ 改变投点次数(100/1000/10000/100000)看精度变化。截图保存 4 个精度的结果。