R 如何在不重复预定义三元组中的特定元素的情况下随机化向量?

R 如何在不重复预定义三元组中的特定元素的情况下随机化向量?,r,conditional,sample,R,Conditional,Sample,我从一个据称很简单的设置开始,结果变得很有挑战性: 比如说,我们有一个碗,里面有W=60个白色的球,B=10个蓝色的球,G=10个绿色的球,Y=10个黄色的球。 现在我开始从那个碗里画三个,并把它们储存起来,直到碗空了。 但是,有一条规则: 规则: 每个三元组不得包含多个相同颜色的非白色球 完成后,我感兴趣的是分别有0、1、2和3个非白色球的三元组的比率 为了解决这个问题,我从绘制和拒绝样本的想法开始,直到有一个样本,它满足了上述规则 我尝试了以下代码(希望可以复制): 虽然这也没有奏效,但我也

我从一个据称很简单的设置开始,结果变得很有挑战性:

比如说,我们有一个碗,里面有W=60个白色的球,B=10个蓝色的球,G=10个绿色的球,Y=10个黄色的球。 现在我开始从那个碗里画三个,并把它们储存起来,直到碗空了。 但是,有一条规则:

规则:

每个三元组不得包含多个相同颜色的非白色球

完成后,我感兴趣的是分别有0、1、2和3个非白色球的三元组的比率

为了解决这个问题,我从绘制和拒绝样本的想法开始,直到有一个样本,它满足了上述规则

我尝试了以下代码(希望可以复制):

虽然这也没有奏效,但我也觉得这种方法不太适合我的问题

总而言之,在我看来,这有点像是我在用大锤敲打坚果,我觉得有一种更有效的方法来解决这个问题(特别是因为我想在事后运行一些蒙特卡罗模拟)

我将感谢任何帮助!
提前谢谢

这里有一种替代方法,毫无疑问可以改进,但我认为这在某种统计上是有意义的(在三个样本中有一种特定的颜色,使得在三个样本中有另一种颜色的可能性更小)


colorsinsamples在Rcpp中实现您的功能。谢谢,@Henry!这确实解决了我的主要问题。现在,我能够基于您的代码构建一个MC模拟,同时包括一些Rcpp(如@Roland建议的)和其他有效的编码方法,以使其更快。我现在唯一要解决的问题是,当对应的值为零时,“结果”表不会显示零,而是简单地删除该值,这导致了一个错误,当我尝试在大量迭代中求和输出时。@FreeEconomist:我不确定您删除值的意思。如果在未设置种子的情况下多次尝试
colorsinsamples(6,1,1,1)
colorsinsamples(3,3,3,3)
,则每次应获得四个值,其中一些值为0。例如,当我使用
colorsinsamples(150,15,15,15)
尝试代码并将种子设置为(3)时,“结果”表忽略第三个值(而不是抛出一个“0”)。尝试
set.seed(3);res确实!我的错!我更改了一些代码,尝试重复函数并将输出存储到全局环境中的向量。不幸的是,我存储在错误的位置,结果是代码末尾的最终if语句没有机会触发。非常感谢您的帮助!
W = rep(0, times = 60)
BGY = c(rep(1, times = 10),rep(2, times = 10),rep(3, times = 10))
sumup = matrix(c(rep(1,times=3)),byrow=FALSE)
OUTPUT = c(0,0,0,0) 

getBALLS = function(W,BGY){
  k = 0
  while (k == 0){
    POT = c(W, BGY)
    STEPS = (length(W) + length(BGY))/3 
    randPOT <<- sample(POT, STEPS*3, replace=FALSE)
    for(j in 1:STEPS){
      if (.subset2(randPOT,3*j-2)!=.subset2(randPOT,3*j-1) &&
          .subset2(randPOT,3*j-2)!= .subset2(randPOT,3*j) && 
          .subset2(randPOT,3*j-1)!=.subset2(randPOT,3*j)){
        next
      }
      else getBALLS(W, BGY)
    }
    k = 1
  }
  TABLES = matrix(randPOT, nrow=3, byrow=FALSE)
  Bdistr = t(TABLES) %*% sumup
  for(i in 1:STEPS){
    if (.subset2(Bdistr,i)==1) OUTPUT[1] <<- .subset2(OUTPUT,1)+1
    else if (.subset2(Bdistr,i)==0) OUTPUT[4] <<- .subset2(OUTPUT,4)+1
    else if (.subset2(Bdistr,i)==2) OUTPUT[2] <<- .subset2(OUTPUT,2)+1
    else OUTPUT[3] <<- .subset2(OUTPUT,3)+1
  }
  rOUTPUT = OUTPUT/ STEPS
  return(rOUTPUT)
}    

set.seed(1)
getBALLS(W,BGY)
Stage1 = c( rep(0,12), rep(1,3), rep(2,3) )
Stage2 = c( rep(0,12), rep(1,3), rep(2,3) )
b = data.frame(Stage1, Stage2)
probs = list( list( (1/12) , (1/3), (1/3) ), list( rep(1/12,12),rep(1/3,3),rep(1/3,3) ) )
m = mstage( b, stage = list("cluster","cluster"), varnames = list("Stage1","Stage2"), 
            size = list(3,c(1,1,1)), method = "systematic", pik = probs)
coloursinsamples <- function (W,B,G,Y){
    WBGY <- c(W,B,G,Y)
    if(sum(WBGY) %% 3 != 0){ warning("cannot take exact full sample") }
    numbersamples <- sum(WBGY) / 3 
    if(max(WBGY[2:4]) > numbersamples){ warning("too many of a colour") }

    weights <- rep(3,numbersamples)
    sampleB <- sample(numbersamples, size=WBGY[2], prob=weights)
    weights[sampleB] <- weights[sampleB]-1
    sampleG <- sample(numbersamples, size=WBGY[3], prob=weights)
    weights[sampleG] <- weights[sampleG]-1
    sampleY <- sample(numbersamples, size=WBGY[4], prob=weights)
    weights[sampleY] <- weights[sampleY]-1

    numbercolours <- table(table(c(sampleB,sampleG,sampleY)))
    result <- c("0" = numbersamples - sum(numbercolours), numbercolours)
    if(! "1" %in% names(result)){ result <- c(result, "1"=0) }
    if(! "2" %in% names(result)){ result <- c(result, "2"=0) }
    if(! "3" %in% names(result)){ result <- c(result, "3"=0) }
    result[as.character(0:3)]
    }

set.seed(1)
coloursinsamples(6,1,1,1)
coloursinsamples(60,10,10,10)
coloursinsamples(600,100,100,100)
coloursinsamples(6000,1000,1000,1000)