Simulating Monty Hall’s Problem

[This article was first published on Jason Bryer, and kindly contributed to R-bloggers]. (You can report issue about the content on this page here)
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.

I find that when teaching statistics (and probability) it is often helpful to simulate data first in order to get an understanding of the problem. The Monty Hall problem recently came up in a class so I implemented a function to play the game.

The Monty Hall problem results from a game show, Let’s Make a Deal, hosted by Monty Hall. In this game, the player picks one of three doors. Behind one is a car, the other two are goats. After picking a door the player is shown the contents of one of the other two doors, which because the host knows the contents, is a goat. The question to the player: Do you switch your choice?

For more information, be sure to see the Wikipedia article.

Below we implement a function that will simulate a single play of this game. You can play interactively, or if you specify the pick and switch parameters this can be looped in order to simulate the results.

monty_hall <- function(pick, switch) {
    interactive <- FALSE
    if(missing(pick)) {
        interactive <- TRUE
        cat('Pick your door:')
        pick <- LETTERS[menu(c('A', 'B', 'C'))]
    } else {
        if(!pick %in% LETTERS[1:3]) {
            stop('pick must be either A, B, or C')
        }
    }
    doors <- c('win', 'lose', 'lose')
    doors <- sample(doors) # Shuffle the doors
    names(doors) <- LETTERS[1:3]
    if(doors[pick] == 'win') {
        show <- sample(names(doors[!names(doors) %in% pick]), size = 1)
    } else {
        show <- doors[!names(doors) %in% pick] == 'lose'
        show <- names(which(show == TRUE))
    }
    if(missing(switch)) {
        interactive <- TRUE
        cat(paste0('Showing door ', show, '. Do you want to switch your choice?'))
        switch <- menu(c('yes', 'no')) == 1
    }
    if(switch) {
        pick <- names(doors)[!names(doors) %in% c(show, pick)]
    }
    win <- unname(doors[pick] == 'win')
    if(interactive) {
        if(win) {
            cat('You win!')
        } else {
            cat('Sorry, you lost.')
        }
        invisible(win)
    } else {
        return(win)
    }
}

We can play a single game:

monty_hall()
Pick your door:
1: A
2: B
3: C

Selection: 2
Showing door A. Do you want to switch your choice?
1: yes
2: no

Selection: 1
You win!

Let’s now simulate 1,000 games. We will use two vectors, mh_switch and mh_no_switch, to store the results after switching doors or not, respectively. For each iteration, the initial door pick is randomly selected.

n_games <- 1000
mh_switch <- logical(n_games)
mh_no_switch <- logical(n_games)
for(i in 1:n_games) {
    pick <- sample(LETTERS[1:3], size = 1)
    mh_switch[i] <- monty_hall(pick = pick, switch = TRUE)
    mh_no_switch[i] <- monty_hall(pick = pick, switch = FALSE)
}

The probability of winning if we switch the door is:

mean(mh_switch)
[1] 0.671

The probability of winning if we do not switch the door is:

mean(mh_no_switch)
[1] 0.328

It should be noted that the theoretical probability of winning if you switch is 2/3, and is 1/3 if you don’t switch.

To leave a comment for the author, please follow the link and comment on their blog: Jason Bryer.

R-bloggers.com offers daily e-mail updates about R news and tutorials about learning R and many other topics. Click here if you're looking to post or find an R/data-science job.
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.

Never miss an update!
Subscribe to R-bloggers to receive
e-mails with the latest R posts.
(You will not see this message again.)

Click here to close (This popup will not appear again)