Выборка из нормального распределения с использованием цикла for - PullRequest
0 голосов
/ 19 февраля 2020

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

Now let's loop through 1000 times, sampling 20 values from a uniform distribution and computing the mean of the sample, saving this mean to a variable called sampMean within a tibble called uniformSampleMeans.
{r 2c}

unif_sample_size = 20 # sample size
n_samples = 1000 # number of samples

# set up q data frame to contain the results
uniformSampleMeans <- tibble(sampMean = runif(n_samples, unif_sample_size))


# loop through all samples.  for each one, take a new random sample, 
# compute the mean, and store it in the data frame

for (i in 1:n_samples){
  uniformSampleMeans$sampMean[i] = summarize(uniformSampleMeans = mean(unif_sample_size))
}

Я успешно генерирую тиббл, однако значения «NaN». Кроме того, когда я добираюсь до моего за oop, я получаю ошибку.

Error in summarise_(.data, .dots = compat_as_lazy_dots(...)) : argument ".data" is missing, with no default

Любое понимание будет высоко ценится!

Ответы [ 4 ]

3 голосов
/ 19 февраля 2020

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

Кроме того, поймите, что брать много маленьких случайных выборок намного дороже, чем брать только одну большую выборку.

set.seed(42)
m <- matrix(rnorm(1000*20), ncol = 20)
head(m)
#        [,1]   [,2]   [,3]   [,4]   [,5]    [,6]   [,7]    [,8]    [,9]   [,10]  [,11]   [,12]
# [1,]  1.371  2.325  0.251 -0.686 -0.142  0.0712  0.173  1.4163 -0.0575 -0.9221  1.163 -0.2945
# [2,] -0.565  0.524 -0.278 -0.793 -0.814  0.9703 -1.273  0.5572 -0.2490 -0.4958 -0.190  0.4641
# [3,]  0.363  0.971 -1.725 -0.407 -0.326  0.3100 -0.868  0.9812 -1.5242 -3.1105 -0.289 -1.5371
# [4,]  0.633  0.377 -2.007 -1.149  0.378 -0.1395  0.626 -0.5862  0.4636 -0.6928 -0.399  0.9862
# [5,]  0.404 -0.996 -1.292  1.116 -1.994 -0.3263 -0.106  0.9392 -1.1876  0.2989  0.709  0.6302
# [6,] -0.106 -0.597  0.366 -0.879 -0.999 -0.1188 -0.256 -0.0647  0.4941 -0.0687 -1.623  0.0573
#        [,13]    [,14]    [,15]  [,16]  [,17]  [,18]   [,19]  [,20]
# [1,]  0.0538 -1.80043 -2.29607 -1.020  0.496  0.110  1.0251  1.790
# [2,]  0.7534 -0.10643  0.00465 -0.754  0.519 -0.741 -1.4492 -0.262
# [3,]  0.2499  1.83347 -1.61634 -1.226 -0.422 -0.511  1.4175 -1.297
# [4,] -0.4441  1.02390  1.73313 -1.017  0.863 -0.912 -1.0353  0.618
# [5,] -0.0503 -0.00429 -0.67368  1.722 -0.778 -1.293  0.0853 -0.292
# [6,] -0.4678  2.27991 -0.09442  3.000  0.148  0.905  0.2451 -0.301
m2 <- apply(m, 1, mean)
length(m2)
# [1] 1000
head(m2)
# [1]  0.1513 -0.2089 -0.4366 -0.0339 -0.1544  0.0959
mean(m[1,])
# [1] 0.151
tibble(i = seq_along(m2), mu = m2)
# # A tibble: 1,000 x 2
#        i      mu
#    <int>   <dbl>
#  1     1  0.151 
#  2     2 -0.209 
#  3     3 -0.437 
#  4     4 -0.0339
#  5     5 -0.154 
#  6     6  0.0959
#  7     7  0.105 
#  8     8 -0.503 
#  9     9  0.0384
# 10    10 -0.175 
# # ... with 990 more rows
0 голосов
/ 19 февраля 2020

Учитывая, что вы пометили это как dplyr вопрос, вы можете использовать summarise_all:

library(dplyr)

n_obs = 20 
n_samples = 1000 

samples <- data.frame(matrix(runif(n_obs * n_samples), nrow = 20))

summarise_all(samples, mean)

Как уже отмечали другие, это можно сделать и в базе R.

Обновление За комментарий OP
Да, возможно использовать a для l oop, хотя это не рекомендуется. Вот один из подходов:

unif_sample_size = 20 
n_samples = 1000 
total_draws <- unif_sample_size * n_samples

uniformSampleMeans <- 
  tibble(draw_from_uniform = runif(n_samples * unif_sample_size))

sample_means <- vector(length = n_samples)

i <- 1
for (ix in seq(1, total_draws, by = unif_sample_size)) {
  start <- ix
  end <- ix + unif_sample_size - 1
  sample_means[i] <- mean(uniformSampleMeans$draw_from_uniform[start:end])
  i <- i + 1
}
0 голосов
/ 19 февраля 2020

Если вы хотите сгенерировать 1000 повторений выборки из случайного равномерного распределения с 20 наблюдениями (и минимумом 0, и максимумом 1), а затем взять среднее значение для каждой выборки, вот краткий способ сделать это с tidyverse:

library(tidyverse)

uniform_samples <- map(1:1000, ~ runif(20, 0, 1))
uniform_sample_means <- map_dbl(uniform_samples, ~ mean(.x))

0 голосов
/ 19 февраля 2020

Для этого вам не нужен dplyr.

rep<-1000
size<-20

# initialize the dataframe
res<-data.frame(rep=NA,mean=NA)

for ( i in 1:rep) {
        samp<-rnorm(size) # here you actually create your sample of 20 numbers from the normal distribution
        res[i,]$rep<-i #save in the first column the number of the replicate sampling (optional)
        res[i,]$mean<-mean(samp) # here you calculate the mean of the random sample and store it into the datafra
}
res
...