【问题标题】:Monty Hall In R - setdiff unexpected resultsMonty Hall In R - setdiff 出乎意料的结果
【发布时间】:2018-07-15 16:08:16
【问题描述】:

我正在用 R 编写一个程序来模拟这里解释的蒙蒂霍尔问题,https://www.youtube.com/watch?v=4Lb-6rxZxx0

考虑这段代码,sample(setdiff(doors, c(pick, car)),1)“应该”每次都为 3,但事实并非如此。

doors <- 1:3
pick <- 2
car <- 1
sample(setdiff(doors, c(pick, car)),1)
[1] 3
sample(setdiff(doors, c(pick, car)),1)
[1] 1

知道我哪里出错了吗?

谢谢。

【问题讨论】:

    标签: r sample do.call set-difference


    【解决方案1】:

    你的问题是你最终打电话给sample.int,因为

    doors <- 3L
    pick <- sample(doors, 1)
    car <- sample(doors, 1)
    class(setdiff(doors, c(pick, car)))
    #R [1] "integer"
    

    和

    length(setdiff(doors, c(pick, car)))
    #R [1] 1
    

    见help("sample.int")或

    body(sample)
    #R {
    #R    if (length(x) == 1L && is.numeric(x) && is.finite(x) && x >= 
    #R         1) {
    #R         if (missing(size)) 
    #R            size <- x
    #R         sample.int(x, size, replace, prob)
    #R     }
    #R    else {
    #R        ...
    

    除非您的集合中有多个变量,否则抽样没有意义。

    【讨论】:

    • 它在文档中,我太专注于 setdiff 我没有检查示例。来自示例文档:“如果 x 的长度为 1,是数字(在 is.numeric 的意义上)并且 x >= 1,则通过 sample 进行采样从 1:x 开始。”
    • 对,就像我上面写的那样,它只需要numeric 和integer。
    • @mks212 由于body(sample) 的其余部分在此答案中被截断,我将指出一个(可能很明显)事实,即如果您想要一个大小为 1 的向量样本 vec长度可能是也可能不是1,你可以做vec[sample.int(length(vec), 1)],这就是else{...}中所做的事情
    【解决方案2】:

    这是我为解决问题而编写的最终代码。我使用 if 语句仅在必要时调用 sample,这是候选人选择车门的情况。我觉得听到额外的条件语句比强迫样本以非预期方式工作的成本更有价值。

      doors <- 1:3
      trials <- 1000
    
      games <- do.call(rbind, lapply(1:trials, function(i){
        pick <- sample(doors, 1)
        car <- sample(doors, 1)
        #open the door the contestant didn't pick and isn't the car
        open_door <- setdiff(doors, c(pick, car))
        #if pick and car are the same, there are two possible doors to open
        #so pick one at random
        #note, sample will malfunction if there is only 1 int passed to it. See documentation.
        #this is the reason for if statement, only deal with the case where there is more than 
        #one int passed
        if(length(open_door)>1) open_door <- sample(open_door, 1)
        #switch to the door that isn't picked and is closed
        switch_to <- setdiff(doors, c(pick, open_door)) 
    
        data.frame(pick, car, open_door, switch_to)
      }))
    
      games$switch_wins <- ifelse(games$switch_to == games$car, 1, 0)
      games$stay_wins <- ifelse(games$pick == games$car, 1, 0)
    
      cat("Switch wins: ", sum(games$switch_wins)/nrow(games), "Stay wins: ", 
          sum(games$stay_wins)/nrow(games), "\n")
    

    输出:

    Switch wins:  0.672 Stay wins:  0.328 
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-25
      • 1970-01-01
      • 2016-09-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多