R中患者健康的编程概率
Programming probability of patients being well in R
首先,我是一个完全的 R 新手。
我有以下问题:
考虑一个简单的进步模型 year-by-year。在第 i 年,令 W_i = 患者健康,I_i = 患者生病,D_i = 患者死亡。转换可以建模为一组条件概率。
令 L = 患者健康的年数。
我得出 L 的概率质量函数为 P(L)=(1-p)(p)^{L-1}。
给定的信息是患者在第 1 年身体状况良好,并考虑到他们的年龄和风险因素,对于所有 i
,P(W_{i+1}|W_{i})=0.2
问题是在 R 中编写一个函数来模拟单个患者的轨迹和 returns 患者健康的年数。
我认为可以使用 rbinom 函数在 R 中将其编程为二项分布。对于单个患者,
rbinom(1, 1, 0.2)
但我认为这不会 return 患者康复的年数。我认为 rbinom 函数应该是开始,它需要搭配一种方法来计算患者健康的年数,但我不知道该怎么做。
下一个问题是使用 R 模拟 1000 个患者轨迹并找到健康年数的样本均值。我假设这将是前一部分的扩展,只需用 1000 名患者替换 1 名患者。但是我不太清楚在哪里用 1000 名替换 1:n 或 size
rbinom(n, size, prob)
这是假设首先使用 rbinom 是正确的做法...
如果我要用另一种编程语言(比如 Python)执行此操作,我将使用一个以 patient_status=W 为条件的 while 循环,并从 L=0 开始迭代循环并在每次成功的迭代中加 1。我不确定 R 是否以同样的方式工作。
让我们从 rbinom(1, 1, 0.2)
的作用开始:它将 returns 1
1
个独立伯努利(即 0-1)个随机变量的实例加在一起有 0.2
等于 1 的概率。因此,该行只会输出 0(80% 的时间执行)或 1(另外 20% 的时间执行) .如您所述,这不是您想要的。
这里的问题是随机变量的选择。二项式变量非常适合 "I roll ten dice. How many land on 6?",因为它具有以下基本组成部分:
- 结果分为成功/失败
- 固定次数(十次)的试验
- 一致的成功概率 (1/6)
- 独立试验(骰子互不影响)
您描述的情况不具备这些特征。那么,怎么办?
选项 1:根据您的直觉进行 while()
循环。作为序言,由于各种原因(主要是效率低下),R 中不鼓励使用 while()
循环。但是,既然您已经理解了这个概念,那么让我们 运行 来理解它。
one_patient <- function(){
status <- 1 # 1 = healthy, 0 = ill
years <- (-1) # count how many years completed while healthy
while(status == 1){
years <- years + 1 # this line will run at least one time
status <- rbinom(1, 1, 0.2) # your rbinom(1, 1, 0.2) line makes an appearance!
}
return(years)
}
现在,执行 one_patient()
将得出患者成功从一个井过渡到另一个井的年数。这将至少为 0,因为 years
从 -1 开始并且至少递增一次。如果患者幸运的话,它可能会非常高,尽管很可能不会。您可以通过将 0.2 参数更改为更乐观的参数(例如 0.99)来对此进行试验,以模拟长寿命。
选项 2:重新考虑随机变量。我在上面提到变量不是二项式的;事实上,它是 几何。像 "I roll a die until it lands on 6. How many rolls did it take?" 这样的情况是几何的,因为它具有以下基本组成部分:
- 结果分为成功/失败
- 一致的成功概率
- 在第一次成功时终止的重复试验
- 独立试验
就像二项式变量在 R 中如何具有有用的函数,例如 rbinom(), pbinom(), qbinom(), dbinom()
,几何变量有一个相应的集合:rgeom(), pgeom(), qgeom(), dgeom()
.
要使用rgeom()
,我们需要注意一个细节:这里,"success"被表征为病人生病,因为那是当实验结束时。 (上文中,通过将患者健康编码为 1,我们隐含地使用了反向视角。)这意味着 "success" 概率为 0.8。 rgeom(1, 0.8)
将 return 抽取次数 严格在 第一次成功之前,这相当于患者从一口井到另一口井的年数,如上所述。请注意,参数 1 指的是我们想要 运行 这个实验的次数,而不是其他的。因此:
rgeom(1, 0.8)
将完成与我们上面定义的 one_patient()
函数相同的任务。 (也就是说,每个输出的分布都是相同的。)
对于多个患者,可以将one_patient()
函数包裹在replicate()
中,也可以直接调整rgeom(1, 0.8)
的第一个参数。第二个选项 快 很多,尽管如果只模拟 1000 名患者,两者都很快。
附录
两者作用相同的证明:
sims1 <- replicate(10000, one_patient())
hist(sims1, breaks = seq(-0.5, max(sims1) + 0.5, by = 1))
sims2 <- rgeom(10000, 0.8)
hist(sims2, breaks = seq(-0.5, max(sims2) + 0.5, by = 1))
证明 rgeom()
更快:
library(microbenchmark)
microbenchmark(
replicate(10000, one_patient()),
rgeom(10000, 0.8)
)
#Unit: milliseconds
# expr min lq mean median uq max neval
# replicate(10000, one_patient()) 35.4520 38.77585 44.135562 43.82195 46.05920 73.5090 100
# rgeom(10000, 0.8) 1.1978 1.22540 1.273766 1.23640 1.27485 1.9734 100
首先,我是一个完全的 R 新手。
我有以下问题:
考虑一个简单的进步模型 year-by-year。在第 i 年,令 W_i = 患者健康,I_i = 患者生病,D_i = 患者死亡。转换可以建模为一组条件概率。
令 L = 患者健康的年数。
我得出 L 的概率质量函数为 P(L)=(1-p)(p)^{L-1}。
给定的信息是患者在第 1 年身体状况良好,并考虑到他们的年龄和风险因素,对于所有 i
问题是在 R 中编写一个函数来模拟单个患者的轨迹和 returns 患者健康的年数。
我认为可以使用 rbinom 函数在 R 中将其编程为二项分布。对于单个患者,
rbinom(1, 1, 0.2)
但我认为这不会 return 患者康复的年数。我认为 rbinom 函数应该是开始,它需要搭配一种方法来计算患者健康的年数,但我不知道该怎么做。
下一个问题是使用 R 模拟 1000 个患者轨迹并找到健康年数的样本均值。我假设这将是前一部分的扩展,只需用 1000 名患者替换 1 名患者。但是我不太清楚在哪里用 1000 名替换 1:n 或 size
rbinom(n, size, prob)
这是假设首先使用 rbinom 是正确的做法... 如果我要用另一种编程语言(比如 Python)执行此操作,我将使用一个以 patient_status=W 为条件的 while 循环,并从 L=0 开始迭代循环并在每次成功的迭代中加 1。我不确定 R 是否以同样的方式工作。
让我们从 rbinom(1, 1, 0.2)
的作用开始:它将 returns 1
1
个独立伯努利(即 0-1)个随机变量的实例加在一起有 0.2
等于 1 的概率。因此,该行只会输出 0(80% 的时间执行)或 1(另外 20% 的时间执行) .如您所述,这不是您想要的。
这里的问题是随机变量的选择。二项式变量非常适合 "I roll ten dice. How many land on 6?",因为它具有以下基本组成部分:
- 结果分为成功/失败
- 固定次数(十次)的试验
- 一致的成功概率 (1/6)
- 独立试验(骰子互不影响)
您描述的情况不具备这些特征。那么,怎么办?
选项 1:根据您的直觉进行 while()
循环。作为序言,由于各种原因(主要是效率低下),R 中不鼓励使用 while()
循环。但是,既然您已经理解了这个概念,那么让我们 运行 来理解它。
one_patient <- function(){
status <- 1 # 1 = healthy, 0 = ill
years <- (-1) # count how many years completed while healthy
while(status == 1){
years <- years + 1 # this line will run at least one time
status <- rbinom(1, 1, 0.2) # your rbinom(1, 1, 0.2) line makes an appearance!
}
return(years)
}
现在,执行 one_patient()
将得出患者成功从一个井过渡到另一个井的年数。这将至少为 0,因为 years
从 -1 开始并且至少递增一次。如果患者幸运的话,它可能会非常高,尽管很可能不会。您可以通过将 0.2 参数更改为更乐观的参数(例如 0.99)来对此进行试验,以模拟长寿命。
选项 2:重新考虑随机变量。我在上面提到变量不是二项式的;事实上,它是 几何。像 "I roll a die until it lands on 6. How many rolls did it take?" 这样的情况是几何的,因为它具有以下基本组成部分:
- 结果分为成功/失败
- 一致的成功概率
- 在第一次成功时终止的重复试验
- 独立试验
就像二项式变量在 R 中如何具有有用的函数,例如 rbinom(), pbinom(), qbinom(), dbinom()
,几何变量有一个相应的集合:rgeom(), pgeom(), qgeom(), dgeom()
.
要使用rgeom()
,我们需要注意一个细节:这里,"success"被表征为病人生病,因为那是当实验结束时。 (上文中,通过将患者健康编码为 1,我们隐含地使用了反向视角。)这意味着 "success" 概率为 0.8。 rgeom(1, 0.8)
将 return 抽取次数 严格在 第一次成功之前,这相当于患者从一口井到另一口井的年数,如上所述。请注意,参数 1 指的是我们想要 运行 这个实验的次数,而不是其他的。因此:
rgeom(1, 0.8)
将完成与我们上面定义的 one_patient()
函数相同的任务。 (也就是说,每个输出的分布都是相同的。)
对于多个患者,可以将one_patient()
函数包裹在replicate()
中,也可以直接调整rgeom(1, 0.8)
的第一个参数。第二个选项 快 很多,尽管如果只模拟 1000 名患者,两者都很快。
附录
两者作用相同的证明:
sims1 <- replicate(10000, one_patient())
hist(sims1, breaks = seq(-0.5, max(sims1) + 0.5, by = 1))
sims2 <- rgeom(10000, 0.8)
hist(sims2, breaks = seq(-0.5, max(sims2) + 0.5, by = 1))
证明 rgeom()
更快:
library(microbenchmark)
microbenchmark(
replicate(10000, one_patient()),
rgeom(10000, 0.8)
)
#Unit: milliseconds
# expr min lq mean median uq max neval
# replicate(10000, one_patient()) 35.4520 38.77585 44.135562 43.82195 46.05920 73.5090 100
# rgeom(10000, 0.8) 1.1978 1.22540 1.273766 1.23640 1.27485 1.9734 100