抛100枚硬币正面朝上数量在40-60之间(含)的概率求解及对应R语言代码错误排查
嗨,我来帮你搞定这个抛硬币概率问题,以及你代码里的那些bug!
先说说问题本身:计算正面数在40-60之间的概率
抛100枚公平硬币,正面朝上的数量X服从二项分布(X ~ Binomial(n=100, p=0.5))。我们要算的是P(40 ≤ X ≤ 60)。
- 如果你想要精确结果,可以直接用R的
pbinom函数计算:
运行后会得到约0.9648,也就是大概96.5%的概率。pbinom(60, 100, 0.5) - pbinom(39, 100, 0.5) - 用模拟的方法也可以得到近似结果,但得先把你的代码改对。
你的代码里的错误在哪里?
咱们一条条看:
- 函数名写错了:你定义的函数叫
Problem(),但调用的时候用的是ProblemTwo()——这明显是笔误,要是没提前定义过ProblemTwo(),R直接会报错的。 - 逻辑判断完全搞反了:
sum(...)==50|60这个表达式的逻辑错得离谱。在R里,|是逻辑或,而单独写60会被当成TRUE(因为非零数值在逻辑判断里都是真)。所以不管正面数量是多少,(正面数等于50) 或 TRUE的结果永远是TRUE,这就是为什么你的mean()一直返回1——所有模拟结果都是真,均值自然是1。 - 函数有点冗余:你的
Problem()返回的是所有硬币的结果向量,但其实我们只需要正面的数量,直接在函数里计算会更高效。
修正后的模拟代码
这里给你两种修正后的版本,任选其一就行:
基础版(不需要额外包)
# 定义单次实验:直接返回正面朝上的数量 single_trial <- function() { sum(sample(c('H','T'), 100, replace = TRUE) == 'H') } # 重复10000次实验,统计符合条件的比例 simulations <- replicate(10000, single_trial()) mean(simulations >= 40 & simulations <= 60)
更简洁的版本(用dplyr的between函数)
如果你已经安装了dplyr包,可以用它的between()函数让代码更易读:
library(dplyr) single_trial <- function() { sum(sample(c('H','T'), 100, replace = TRUE) == 'H') } mean(replicate(10000, between(single_trial(), 40, 60)))
运行修正后的代码,结果会接近理论值0.96左右,和精确计算的结果一致。
内容的提问来源于stack exchange,提问作者Abdulrazzaq
相关产品推荐
相关产品推荐

