就概率分布而言,它们使用什么?我知道runif给出的是小数,sample给出的是整数,但我感兴趣的是,sample是否也使用“均匀概率分布”?
请看以下代码和输出:
> set.seed(1)
> round(runif(10,1,100))
[1] 27 38 58 91 21 90 95 66 63 7
> set.seed(1)
> sample(1:100, 10, replace=TRUE)
[1] 27 38 58 91 21 90 95 67 63 7
这强烈表明,当要求做相同的事情时,这两个函数产生的输出基本相同(有趣的是,产生相同输出的是round
而不是floor
或者ceiling
)。主要区别在于默认值,如果您不更改这些默认值,则两者都将给出称为均匀分布的东西(虽然sample
将被视为离散均匀分布,并且默认情况下不会替换)。
编辑
更正确的比较是:> ceiling(runif(10,0,100))
[1] 27 38 58 91 21 90 95 67 63 7
使用round
的替代方法。
我们甚至可以再往上提升一级:
> set.seed(1)
> tmp1 <- sample(1:100, 1000, replace=TRUE)
> set.seed(1)
> tmp2 <- ceiling(runif(1000,0,100))
> all.equal(tmp1,tmp2)
[1] TRUE
当然,如果在 sample
中使用了 probs
参数(而不是所有的值都相等),那么它将不再是均匀的。sample
从一组固定的输入中生成一个或多个样本,如果将长度为1的输入作为第一个参数传递,则返回整数输出。
另一方面,runif
从一个实值范围内返回一个样本。
> sample(c(1,2,3), 1)
[1] 2
> runif(1, 1, 3)
[1] 1.448551
sample()
运行速度比ceiling(runif())
更快。
如果进行多次模拟或引导,这是有用的知识。
粗略的时间测试脚本可测试4个等效脚本:
n<- 100 # sample size
m<- 10000 # simulations
system.time(sample(n, size=n*m, replace =T)) # faster than ceiling/runif
system.time(ceiling(runif(n*m, 0, n)))
system.time(ceiling(n * runif(n*m)))
system.time(floor(runif(n*m, 1, n+1)))
比例时间优势随着n和m的增加而增加,但要注意不要填满内存!
顺便说一句,不要使用round()
将均匀分布的连续值转换为均匀分布的整数,因为终端值只有一半的时间被选择。
n <- 1e7; microbenchmark(sample(n, n, TRUE), as.integer(ceiling(runif(n)*n)), times=10)
对于样本和runif分别给出了平均时间684毫秒和467毫秒。对于较小的n(例如n = 1e6),它们几乎相同。 - Nobody
?runif
和?sample
都非常清晰明了。 - Gregor Thomas