使用 for 循环从正态分布中抽样
Sampling from a normal distribution using a for loop
所以我尝试从均匀分布中抽样 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"。此外,当我进入我的 for 循环时,我得到一个错误。
Error in summarise_(.data, .dots = compat_as_lazy_dots(...)) : argument ".data" is missing, with no default
任何见解将不胜感激!
你不需要 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
如果您想做的是从具有 20 个观察值(最小值为 0,最大值为 1)的随机均匀分布中生成样本的 1000 次重复,然后取每个样本的平均值,这是一种简洁的方法使用 tidyverse
:
library(tidyverse)
uniform_samples <- map(1:1000, ~ runif(20, 0, 1))
uniform_sample_means <- map_dbl(uniform_samples, ~ mean(.x))
逐行构建 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
鉴于您已将其标记为 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)
正如其他人所指出的,也可以在 base R 中执行此操作。
更新 根据 OP 评论
是的,可以使用 for 循环,但不建议这样做。这是一种方法:
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
}
所以我尝试从均匀分布中抽样 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"。此外,当我进入我的 for 循环时,我得到一个错误。
Error in summarise_(.data, .dots = compat_as_lazy_dots(...)) : argument ".data" is missing, with no default
任何见解将不胜感激!
你不需要 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
如果您想做的是从具有 20 个观察值(最小值为 0,最大值为 1)的随机均匀分布中生成样本的 1000 次重复,然后取每个样本的平均值,这是一种简洁的方法使用 tidyverse
:
library(tidyverse)
uniform_samples <- map(1:1000, ~ runif(20, 0, 1))
uniform_sample_means <- map_dbl(uniform_samples, ~ mean(.x))
逐行构建 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
鉴于您已将其标记为 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)
正如其他人所指出的,也可以在 base R 中执行此操作。
更新 根据 OP 评论
是的,可以使用 for 循环,但不建议这样做。这是一种方法:
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
}