我有以下四个数字集:
A=[1,207];
B=[208,386];
C=[387,486];
D=[487,586].
我需要生成 20000 个介于 1 和 586 之间的随机数,其中生成的数字属于 A 的概率是 1/2,属于 B、C、D 的概率是 1/6。
我可以通过哪种方式使用 R 来做到这一点?
您可以直接使用sample
,更具体地说是probs
参数。只需将概率除以所有 586 个数字。类别A
获得的0.5/207
权重,等等。
A <- 1:207
B <- 208:386
C <- 387:486
D <- 487:586
L <- sapply(list(A, B, C, D), length)
x <- sample(c(A, B, C, D),
size = 20000,
prob = rep(c(1/2, 1/6, 1/6, 1/6) / L, L),
replace = TRUE)
我会说使用轮盘赌选择方法。我将尝试在这里做一个简短的解释。取一条长度为 1 单位的线。现在按概率值的比例打破这个。所以在我们的例子中,第一块长度为 1.2,接下来的三块长度为 1/6。现在从均匀分布中采样一个介于 0,1 之间的数字。由于所有数字具有相同的发生概率,因此属于一块的采样数将等于该块的长度。因此,该数字也属于哪个部分,从该向量中采样。(我会给你下面的 R 代码,你可以运行它来检查我说的是不是真的。我可能在这里解释得不好。)
它被称为轮盘赌选择,因为对于相同情况的另一个类比可以是,取一个圆圈并将其分成多个扇区,其中每个扇区的角度与概率值成正比。现在再次从均匀分布中采样一个数字,看看它属于哪个扇区,并以相同的概率从该向量中采样
A <- 1:207
B <- 208:386
C <- 387:486
D <- 487:586
cumList <- list(A,B,C,D)
probVec <- c(1/2,1/6,1/6,1/6)
cumProbVec <- cumsum(probVec)
ret <- NULL
for( i in 1:20000){
rand <- runif(1)
whichVec <- which(rand < cumProbVec)[1]
ret <- c(ret,sample(cumList[[whichVec]],1))
}
#Testing the results
length(which(ret %in% A)) # Almost 1/2*20000 of the values
length(which(ret %in% B)) # Almost 1/6*20000 of the values
length(which(ret %in% C)) # Almost 1/6*20000 of the values
length(which(ret %in% D)) # Almost 1/6*20000 of the values