Как мне векторизовать% в% (он же соответствует) в R? - PullRequest
0 голосов
/ 25 декабря 2018

Я пытаюсь смоделировать проблему Монти Холла в теории вероятностей, используя R. Если вы не знакомы, проблема выглядит следующим образом:

Участник на игровом шоу и ему говорят, чтоприз находится за одной из трех дверей.Их просят угадать дверь.Отгадав дверь, хозяин (он же Монти Холл) открывает дверь, в которой нет приза, чтобы помочь участнику.Затем участнику разрешается изменить свое предположение от своей первоначальной двери до другой двери, которая все еще закрыта.Хотя это и не интуитивно понятно, вероятность того, что участник выиграет приз, будет больше, если он изменит свое предположение.

Я выяснил, как смоделировать задачу, используя циклы for в R, но код оченьмедленно, когда я использую миллионы итераций.Я пытался векторизовать код и столкнулся с проблемой при попытке векторизации функции %in% в R. Мне было интересно, знает ли кто-нибудь как.Я только показываю свой код для основного раздела, который я не могу векторизовать.Он идентифицирует дверь, на которую участник может изменить свою догадку.

for (i in 1:f) {
    change[i] <- doors[i, !(doors[i, ] %in% c(guess[i], open[i]))]
}
  • f - это число итераций в симуляции (или число случайных участников).
  • doors - это матрица с f строками, каждый из которых равен c(1, 2, 3), что соответствует трем дверям в игре.
  • guess - исходное предположение участника.
  • open - это дверь, которую открыл хозяин.
  • change - это дверь, на которую участник может изменить свое предположение.

Вот полный коддля тех, кому интересно:

# MONTY HALL PROBABILITY PROBLEM SIMULATION ####
montyHall <- function(f = 100, change = TRUE) {

  # randoms
  option <- matrix(data = rep.int(x = c(1, 2, 3), times = f),
                   nrow = f, ncol = 3, byrow = TRUE)
  correct <- sample.int(n = 3, size = f, replace = TRUE)
  guess <- sample.int(n = 3, size = f, replace = TRUE)
  result <- data.frame("correct" = correct, "guess" = guess)

  # door selection
  temp <- vector(mode = "list", length = f)
  result[, "door"] <- rep.int(x = -999, times = f)
  for (i in 1:f) {
    temp[[i]] <- option[i, !(option[i, ] %in% c(result[i, "correct"], result[i, "guess"]))]
    if (length(temp[[i]]) == 1) {result[i, "door"] <- temp[[i]]}
    if (length(temp[[i]]) == 2) {result[i, "door"] <- sample(x = temp[[i]], size = 1)}
  }

  # change door
  result[, "change"] <- rep.int(x = NA, times = f)
  for (i in 1:f) {
    result[i, "change"] <- option[i, !(option[i, ] %in% c(result[i, "guess"], result[i, "door"]))]
  }

  # outcomes
  if (change == FALSE) {
    result[, "win"] <- ifelse(result[, "guess"] == result[, "correct"],
                              yes = 1, no = 0)
  }
  if (change == TRUE) {
  result[, "win"] <- ifelse(result[, "change"] == result[, "correct"],
                              yes = 1, no = 0)
  }
  if (!is.logical(change)) {
    stop("the change argument must be logical")
  }
  win <- sum(result[, "win"], na.rm = FALSE)
  # if win = NA then something went wrong

  # output
  output <- round(x = win / i, digits = 2)
  return(output)
}
montyHall(f = 1000000, change = FALSE)
montyHall(f = 1000000, change = TRUE)

1 Ответ

0 голосов
/ 25 декабря 2018

Разница в множествах, которую вы пытаетесь получить, может быть достигнута с помощью setdiff (см. документы ).также, посоветуйте этот базовый урок о том, как выполнять однострочные циклы.рассмотрим следующий код для ваших нужд:

f <- 10
doors <- matrix(rep(1:3,f),nrow=f, byrow = T)
guess <- sample(1:3,f,replace = T)
change <- rep(0,f)
open <- sample(1:3,f,replace = T)
sapply(1:f,function(x) setdiff(doors[x,],c(guess[x], open[x])))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...