Рисование из двух распределений с вероятностью в R

Я пытаюсь сделать из двух разных распределений с вероятностью 100000 раз. К сожалению, я не вижу, что не так с моим циклом for, однако он добавляет только 1 значение к simulated_data вместо желаемых 100 000 значений.

Вопрос 1: Как я могу это исправить?

Вопрос 2: Есть ли гораздо более эффективный метод, при котором мне не нужно перебирать 100 000 элементов в списке?

#creating a vector of probabilities
probabilities <- rep(0.99,100000)
#creating a vector of booleans
logicals <- runif(length(probabilities)) < probabilities

#empty list for my simulated data
simulated_data <- c()

#drawing from two different distributions depending on the value in logicals
for(i in logicals){

  if (isTRUE(i)) {
    simulated_data[i] <- rnorm(n = 1, mean = 0, sd = 1)
  }else{
     simulated_data[i] <- rnorm(n = 1, mean = 0, sd = 10)
   }
}

3 ответа

Кажется, что вы хотите создать окончательную выборку, в которой каждый элемент выбирается случайным образом из sample1 или sample2 с вероятностями 0,99 и 0,01.

Правильный подход состоит в том, чтобы генерировать обе выборки, каждая из которых содержит одинаковое количество элементов, а затем случайным образом выбирать одну из них.

Правильный подход будет:

# Generate both samples
n = 100000
sample1 = rnorm(n,0,1)
sample2 = rnorm(n,0,10)

# Create the logical vector that will decide whether to take from sample 1 or 2
s1_s2 = runif(n) < 0.99

# Create the final sample
sample = ifelse(s1_s2 , sample1, sample2)

В этом случае не гарантируется, что имеется ровно 0,99 * n образцов из sample1 и 0,01*n из sample2. По факту:

> sum(sample == sample1)
[1] 98953

Это близко к 0,99 * n, как и ожидалось, но не совсем.

Создайте вектор с нужной долей значений из каждого распределения, а затем создайте случайную перестановку значений:

N = 10000
frac =0.99
rand_mix = sample( c( rnorm( frac*N, 0, sd=1) , rnorm( (1-frac)*N, 0, sd=10) ) )

> table( abs(rand_mix) >1.96)

FALSE  TRUE 
 9364   636 
> (100000-636)/100000
[1] 0.99364

> table( rnorm(10000) >6)

FALSE 
10000 

Фракция фиксированная. Если вы хотите получить случайную дробь (статистически близкую к 0,99), попробуйте следующее:

> table( sample( c( rnorm(10e6), rnorm(10e4, sd=10) ), 10e4) > 1.96 )

FALSE  TRUE 
97151  2849 

Сравнить с:

> N = 100000
> frac =0.99
> rand_mix = sample( c( rnorm( frac*N, 0, sd=1) , rnorm( (1-frac)*N, 0, sd=10) ) )
> table( rand_mix > 1.96 )

FALSE  TRUE 
97117  2883 

Вот хорошее решение для всех, кто здесь:

n <- 100000
prob1 <- 0.99
prob2 <- 1-prob1 

dist1 <- rnorm(prob1*n, 0, 1)
dist2 <- rnorm(prob2*n, 0, 10)

actual_sample <- c(dist1, dist2)
Другие вопросы по тегам