假设我们将头部表示为“0”,尾部为“1”。让P.
假设一枚当前为正面的硬币被抛后仍然是正面的概率,反面也是如此。如果p = = 0.5
,那么掷硬币似乎是不相关的。我们将这个想法作为一个简单的函数来实现
f1 <- function(n, p) {current <- rbinom(1,1,0.5) outcome <- NULL for (i in 1:n) {if(runif(1) > p) current <- (current + 1) %% 2 outcome <- c(outcome, current)} outcome}
这是正确的吗?
f1(10。5)
## [1] 1 1 0 0 0 0 0 0 0 1 0
表(f1 (1000 5))
## ## 0 1 ## 496 504
RES < - F1(1000,.9)平均值(RLE(RES)$ LONGGE)#期望:1 /(1 - P)
## [1] 10.75269
它可以理解吗?几乎
它是强大的吗?我们会回到这个问题。
它快速吗?似乎最初,但它缩放了差不多!
system.time(f1(5000,.5))
##用户系统经过## 0.141 0.019 0.161
System.time(F1(10000,.5))
##用户系统经过## 0.455 0.047 0.503
System.time(F1(20000,.5))
##用户系统经过## 1.796 0.261 2.062
倍增问题大小(N
)会导致执行时间增加4倍。
有什么问题?c(结果,电流)
原因结果
每次通过循环复制!
预先分配和填写结果向量;outome.
更新到位,无需复制。
F2 < - 函数(n,p){clourcy < - rbinom(1,1,0.5)结果< - numeric(n)(i在1:n){if(1)> p)电流< - (当前+ 1)%% 2结果[i] < - current}结果}
这是正确的吗?
Set.seed (123) res2 <- f2(100, .9) identical(res1, res2)
## [1]真实
它可以理解吗?易于理解的f1 ()
。
它是强大的吗?在一分钟内…
它快速吗?
System.time(F2(5000,.5))
## user system elapsed ## 0.029 0.000 0.029
System.time(F2(10000,.5))
##用户系统经过## 0.055 0.001 0.057
System.time(F2(20000,.5))
##用户系统经过## 0.106 0.003 0.111
F2()
似乎线性缩放,因此比较越来越好f1 ()
。
请注意,runif()
叫做N
时间,但程序可以修改,仍然是可以理解的,如果它被称为一次 -提升机runif(1)> p
不知情。
F3 <- function(n, p) {current <- rbinom(1,1,0.5) outcome <- numeric(n) test <- runif(n) > p for (i in 1:n) {if(test[i]) current <- (current + 1) %% 2 outcome[i] <- current} outcome}
set.seed(123)Res1 < - F1(100,.9)Set.seed(123)Res3(100,.9)相同(Res1,Res3)
## [1]真实
可以理解吗?是的。
强壮的?他们都没有,也没有F3()
真的不是!
set.seed(123)F1(0,.5)
## [1] 1 1
set.seed(123)尝试(f3(0,.5))
## IF(测试[i])当前< - (当前+ 1)%% 2:##缺少所需的真/假的值
F3()
n < - 100000 system.time(f2(n,.5))
##用户系统经过## 0.551 0.033 0.587
system.time(f3(n,.5))
## user system elapsed ## 0.043 0.001 0.044
…用线性缩放。
system.time(f3(n * 10,.5))
##用户系统经过## 0.424 0.007 0.434
问题是1:n ..
是不是特别健壮1:0
生成序列C(1,0)
,而我们期待的是一个零长度的序列!
解决方案:使用seq_len(n)
Lapply(3:1,SEQ_LEN)
## [[1]] ## [1] 1 2 3 ## ## [[2]] ## [1] 1 2 ## ## [3]] ## [1] 1
F4 <- function(n, p) {current <- rbinom(1,1,0.5) outcome <- numeric(n) test <- runif(n) > p for (i in seq_len(n)) {if(test[i]) current <- (current + 1) %% 2 outcome[i] <- current} outcome}
正确的?是的
可以理解吗?是的
强壮的?是的
set.seed(123)F4(3,.5)
## [1] 1 1 0
f4(2、5)
## [1] 1 0
F4(1,.5)
## [1] 0
F4(0,.5)
## numeric(0)
用cumsum ()
(康明赛)制备具有相同头部或尾状状态的顺序组。用%%
将这些组转化为正面(cummsum()%% 2 == 0
或背面(Cummsum()%% 2 == 1
)。
F5 < - 功能(n,p){电流< - rbinom(1,1,0.5)测试< - runif(n)> p cumsum(电流+测试)%% 2}
set.seed(123);Res1 < - F1(10,.8)Set.seed(123);Res5 < - F5(10,.8)相同(Res1,Res5)
## [1]真实
可以理解吗?难以理解……
强壮的?是的
F5(0,.8)
## numeric(0)
N <- 1000000系统。时间(f4 (n, 5))
##用户系统运行## 0.416 0.002 0.420
system.time(f5(n,.5))
##用户系统经过## 0.087 0.002 0.088
system.time(f5(n * 10,.5))
##用户系统运行## 1.151
大约4倍速度比F4()
,线性缩放,快速,甚至非常大N
。
可以用来生成一个大的数据集,用于开发有关相关样本的方法,沿着
correlated_tosses_expts < - 函数(m,n,p){## m折叠(行)中的每个实验start0 < - rep(rbinom(m,1,.5),每个= m)group0 < - cumsum(Runif(m * n)> p)toss < - (start0 + group0)%% 2矩阵(toss,m)} system.time({expt < - correlated_tosses_expts(1000,10000,.8)})
## user system elapsed ## 0.977 0.058 1.035
steg(colsums(expt))
也许我们已经到了收益递减的地步,我们已经花了更多的时间进行开发f5 ()
比我们将通过进一步调查拯救......但是,
当前的
至cumsum ()
向量。rgeom()
生成更改点。其他工具
sessioninfo()
## R版本3.6.1修补(2019-07-16 R76845)##平台:X86_64-Apple-Darwin17.7.0(64位)##正在运行:Macos High Sierra 10.13.6 ## ##矩阵产品:默认## blas:/users/ma38727/bin/r-3-6-branch/lib/liblblas.dylib ## lapack:/users/ma38727/bin/r-3-6-branch/lib/librlapack.dylib### locale:## [1] en_US.UTF-8 / en_US.UTF-8 / EN_US.UTF-8 / C / EN_US.UTF-8 / EN_US.UTF-8 ## ##附加基础包:##[1]统计图形grdevices实用程序数据集方法基础## ##其他附加包:## [1] biocstyle_2.13.2 ## ##通过命名空间加载(且未附加):## [1] biocmanager_1.30.4 Compiler_3.6.1 magrittr_1.5 ## [4] bookdown_0.12 htmltools_0.3.6 tools_3.6.1 ## [7] yaml_2.2.0 rcpp_1.0.1 codeTools_0.2-16 ## [10] Stringi_1.4.3 RmarkDown_1.14 Knitr_1.23##[13] stringr_1.4.0 digest_0.6.20 xfun_0.8 ## [16]评估_0.14