用R语言创建样本空间,计算事件发生概率

起初想把标题定为“大一概率习题,难倒了10年R语言大佬”,虽然主题明确,但再三考虑读者的阅读情景,还是用这个“用R语言创建样本空间,计算事件发生概率”标题吧:
1> 写代码着急找函数,标题写一些关键词,易于读者检索;
2> 本篇重点在于讲解题目的R编程实现,而不是讨论中西教育差异;
3> 不要看起来博主技术很菜。

表弟今年去英国读书,前几天发给我一份概率论习题,“姐,这个题教授让拿RMarkdown实现,求指导。”
看到题目的那一刻,I am soooooo fang(慌)!!!
这能是大一学习2个月的练习题???完全可以拿来考R专业证书好嘛!!!

题目
随机试验:从n+2张card中随机抽取,1,2,3,...,n是绿牌,n+1,n+2是红牌,取出后不放回,每张牌拿到的概率相等。
1> 抽到第一张红牌之前,所有card都放在X桌上,包括第一张红牌;
2> 接下来抽到的card放在Y桌上,直到抽到第二张红牌,第二张红牌也放在Y桌上;
3> 剩余抽到的card放在Z桌上。
下图为当n=4时,XYZ桌上card组合的一种结果示例。

要求
1> 使用R语言编程计算概率事件,且使用规范的数学符号;
2> 假设n≥2,给出这些问题的答案:
    a) 定义随机实验的样本空间 Ω
    b) 计算样本空间的大小 |Ω|
    c) 定义事件A(3张桌子上都至少有1张绿牌),定义事件B(X桌上至少有1张绿牌)
    d) 计算事件A、事件B发生的概率(验证:当n=4时,P(A)=1/5)

全网搜了2小时资料后,得出一个结论:这个题,“拿来主义”,它不好用了!
为啥呢???
1> 与这个题型相似的资料非常多,但是没有R语言解题的连贯逻辑;
2> 许多技术博客要付费才能查看全文,且提及的函数不适用。
想想自己写一个吧。

接下来分3个部分来说明题目的实现过程:
1. 解题逻辑&函数
2. Rcode示例
3. RMarkdown交作业

一、解题逻辑&函数

1. 解题逻辑

假设:n=4,有n+2张牌,即6张牌,1,2,3,4是绿牌,5,6是红牌。
1> 创建样本空间大矩阵Ω
矩阵Ω的行数为随机试验所有可能结果的总数,列数为card数量;
当取出第一张card时有6种可能,第二张有5种可能,...,第六张有1种可能,也就是总共有 6*5*4*3*2*1=6! 种card排列组合结果,即行数为6! ;
第1列记录第一张card值,第2列记录第二张card值,以此类推,总共六张card,即列数为6;
2> 查找每个事件中两张红牌的位置;
3> 根据红牌位置将随机事件结果赋值给X、Y、Z;
4> 计算每个事件中X、Y、Z分别包含几张绿牌;
5> 定义目标事件&计算概率
图中所示为步骤1-2-3的矩阵示例。

2. R语言相关函数

对于上述解题步骤,涉及到这些R语言操作以及函数使用:
1> 计算N的阶乘:prod(1:N)
2> 生成1:N所有排列组合,调用gtools包中的函数:permutations()
(注意:这里不可以使用sample()函数,sample()只能用来模拟随机事件,不能生成样本空间。)
3> 字符串拼接:paste()
4> 在字符串中查找指定字符的位置,调用stringr包中的函数:str_locate()
5> 字符串截取:str_sub()
6> 计算字符串中指定字符的个数:str_count()
7> 对数据框筛选指定条件的行:subset()

二、 Rcode示例

【1. 创建样本空间Ω】

n<-4# 定义n
N<-n+2 # card数量
cards<-1:N # 牌中包含的数字
library(gtools)
Omega<-permutations(n=N, r=N, v=cards,repeats.allowed=FALSE)# 全排列组合矩阵,不允许重复
Omega<-as.data.frame(Omega)# 矩阵转为数据框格式

【2. 查找2张红牌位置】
分成3段code来实现

# 1. 对每一行生成一个拼接字符串
for (i in 1:prod(1:N)) {
      Omega[i,N+1] <- do.call(paste,c( Omega[i,1:N],sep=''))
 }

# 2. 计算指定字符:n+1、n+2所在位置
library(stringi)
library(stringr)
n1<-as.character(n+1)
n2<-as.character(n+2)
Omega$label1<-str_locate(Omega$V7,n1)# n+1的位置
Omega$label2<-str_locate(Omega$V7,n2)# n+2的位置

# 3. 计算第一次出现红牌、第二次出现红牌的位置
for (i in 1:prod(1:N)) {
  Omega$label_1st_red[i]<-min(Omega$label1[i],Omega$label2[i])# 第一张红牌的位置
  Omega$label_sec_red[i]<-max(Omega$label1[i],Omega$label2[i])# 第二张红牌的位置
 }

【3. 将随机事件结果赋值给X、Y、Z】

# 根据红牌位置截取字符串,生成X、Y、Z的数据集
Omega$table_X<-str_sub(Omega$V7,1,Omega$label_1st_red)
Omega$table_Y<-str_sub(Omega$V7,Omega$label_1st_red+1, Omega $label_sec_red)
Omega$table_Z<-str_sub(Omega$V7,Omega$label_sec_red+1,N)

【4. 计算每个事件中X、Y、Z分别包含几张绿牌】

for (i in 1:prod(1:N)) {
  Omega$table_X_green_count[i]<-sum(str_count(Omega$table_X[i],as.character(c(1:n))))
  Omega$table_Y_green_count[i]<-sum(str_count(Omega$table_Y[i],as.character(c(1:n))))
  Omega$table_Z_green_count[i]<-sum(str_count(Omega$table_Z[i],as.character(c(1:n))))
 }

【5. 定义目标事件&计算概率】

# 事件A:每张桌子都至少有1张绿牌
# 事件B:X桌子上至少有1张绿牌
event_A<-(Omega$table_X_green_count>=1 & Omega$table_Y_green_count>=1 & Omega$table_Z_green_count>=1)
event_B<-(Omega$table_X_green_count>=1)

# 计算事件概率
prob_event_A<-nrow(subset(Omega,event_A))/prod(1:N)
prob_event_B<-nrow(subset(Omega,event_B))/prod(1:N)

# 输出结果
head(Omega)
print(paste0('|Ω|:',prod(1:N)))
print(paste0('P(A):',prob_event_A))
print(paste0('P(B):',prob_event_B))

三、RMarkdown交作业

将Rcode嵌入RMarkdown原文件的代码框中,可以将程序结果输出为HTML、docx、PDF等文件,这部分对rmd文件格式做个简单介绍。

rmd代码主要包括3个模块:
1. 文件信息设置,如:标题、作者、输出文件的格式;
2. 全局设置,如:是否在文件中显示代码部分、警告信息是否写入结果文件;
3. Rcode部分,即代码主体。

1. 文件信息设置

---
title: "用R语言创建样本空间,计算事件发生概率"
author: "千行"
date: "2023/11/11"
output:
    html_document: default
---

2. 全局设置

```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = FALSE)# 文件中不显示代码行
```

3. Rcode部分

```{r results='hold',warning=FALSE}
n<-4# 定义n
N<-n+2 # card数量
cards<-1:N # 牌中包含的数字

library(gtools)
Omega<-permutations(n=N, r=N, v=cards,repeats.allowed=FALSE)# 全排列组合矩阵,不允许重复
Omega<-as.data.frame(Omega)# 矩阵转为数据框格式
head(Omega,10)
```

把R代码主体替换到RMarkdown的Rcode中,点击Knit,就可以交作业啦~

文末:
1> 这个题最难的部分在于样本空间的创建,博主真的是不知道如何快速生成全排列组合,就先用sample()模拟了一个大样本矩阵;
2> 从逻辑到code实现总共用了6小时,后来问了ChatGPT,它1分钟内给出了结果,且代码逻辑精炼、计算过程节省内存,最惊喜的是它检索出了全排列组合函数permutations(),帮助解决了第一步的问题,真棒!
3> 当文心一言慢悠悠走来,让我觉得AI还很远的时候,ChatGPT出现就是一道闪电。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,099评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,828评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,540评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,848评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,971评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,132评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,193评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,934评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,376评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,687评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,846评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,537评论 4 335
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,175评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,887评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,134评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,674评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,741评论 2 351

推荐阅读更多精彩内容