9.2 replication
第4章介绍的rep
函数能把输入的参数重复数次。另一个相关函数replicate
则能调用表达式数次。大多数情况下它们基本相等,只有当使用随机数时才会出现不同。现在,假定生成均匀分布随机数的runif
函数不是矢量化的,那么rep
函数每次都将重复相同的随机数,而replicate
每次的结果都不相同(由于历史的原因,其参数顺序竟然是从后到前的,这有点烦人):
rep(runif(1), 5)
## [1] 0.04573 0.04573 0.04573 0.04573 0.04573
replicate(5, runif(1))
## [1] 0.5839 0.3689 0.1601 0.9176 0.5388
在更为复杂的例子中,replicate
会大显身手。例如,在蒙特卡罗(Monte Carlo)分析中——replicate
最主要的用途,你需要重复固定次数的分析过程且每次迭代都是相互独立的。
下一个例子将分析某人上下班时使用不同交通工具所花费的时间。这有些复杂,不过这是为了展示replicate
的作用,它非常适合于这种场景。
time_for_commute
函数用sample
随机挑选一种交通工具(小汽车、公交车或自行车),然后用rnorm
或rlnorm
找到一个正态分布或对数正态分布1的行程时间(具体参数取决于所选的交通工具)。
1 对数正态分布偶尔会扔出非常大的数字,从而接近高峰期塞车。
time_for_commute <- function()
{
#选择当时所用的交通工具
mode_of_transport <- sample(
c("car", "bus", "train", "bike"),
size = 1,
prob = c(0.1, 0.2, 0.3, 0.4)
)
#根据交通工具,找到出行的时间
time <- switch(
mode_of_transport,
car = rlnorm(1, log(30), 0.5),
bus = rlnorm(1, log(40), 0.5),
train = rnorm(1, 30, 10),
bike = rnorm(1, 60, 5)
)
names(time) <- mode_of_transport
time
}
switch
语句的存在使得这个函数很难被向量化。这意味着:为了找到上下班时间的分布,我们需要多次调用time_for_commute
来生成每天的数据。replicate
使我们能即刻进行向量化:
replicate(5, time_for_commute())
## bike car train bus bike
## 66.22 35.98 27.30 39.40 53.81