我有一个数据框,其中包含样本大小,均值和标准差以及target
值的列:
ssize <- c(200, 300, 150)
mean <- c(10, 40, 50)
sd <- c(5, 15, 65)
target <- c(7, 23, 30)
df <- data.frame(ssize, mean, sd, target)
我希望添加另一个变量below
,该变量返回小于target
值的元素数,这是从具有参数mean
和sd
的正态分布中得出的,并且样本大小ssize
。但是,我无法获得rnorm
来将每一行的值用作参数。例如,运行
df$below <- sum(rnorm(df$ssize, df$mean, df$sd) < df$target)
生成样本大小等于length(df$ssize)
而不是df$ssize
本身的值的分布。
@alistaire和@ G5W的解决方案效果很好,但是我想从每行的100个rmrm复制中提取below
的平均值。我尝试了两种解决方案:
df <- df %>% mutate(below = mean(replicate(100, pmap_int(., ~sum(rnorm(..1, ..2, ..3) < ..4)))))
df$below <- with(df, sapply(1:nrow, function(i) mean(replicate(100, sum(rnorm(n[i], mean[i], sd[i]) < target[i])))))
但是使用我的数据集(行数超过430万)将花费很长时间。是否有可能更快的数据表(或其他)解决方案?
答案 0 :(得分:2)
列表列是执行此操作的自然方法,因此您可以将样本存储在生成样本的参数旁边。使用purrr进行迭代,
library(tidyverse)
set.seed(47) # for reproducibility
df <- data_frame(n = c(200, 300, 150), # rename to name of parameter in rnorm so pmap works naturally
mean = c(10, 40, 50),
sd = c(5, 15, 65),
target = c(7, 23, 30))
df %>%
mutate(samples = pmap(.[1:3], rnorm), # iterate in parallel over parameters and store samples as list column
below = map2_int(samples, target, ~sum(.x < .y))) # iterate over samples and target, calculate number below, and simplify to integer vector
#> # A tibble: 3 x 6
#> n mean sd target samples below
#> <dbl> <dbl> <dbl> <dbl> <list> <int>
#> 1 200 10 5 7 <dbl [200]> 47
#> 2 300 40 15 23 <dbl [300]> 41
#> 3 150 50 65 30 <dbl [150]> 58
答案 1 :(得分:1)
您可以在lapply
和一个临时函数的基础R中完成此操作
df$below = with(df,
sapply(1:3, function(i) sum(rnorm(ssize[i], mean[i], sd[i]) < target[i])))
df$below
[1] 44 45 48