Рисование из двух распределений с вероятностью в 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)