9

我有以下四个数字集:

A=[1,207];
B=[208,386];
C=[387,486];
D=[487,586].

我需要生成 20000 个介于 1 和 586 之间的随机数,其中生成的数字属于 A 的概率是 1/2,属于 B、C、D 的概率是 1/6。

我可以通过哪种方式使用 R 来做到这一点?

4

2 回答 2

17

您可以直接使用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)
于 2013-06-08T17:13:42.813 回答
2

我会说使用轮盘赌选择方法。我将尝试在这里做一个简短的解释。取一条长度为 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
于 2013-06-08T17:24:29.527 回答