在R中按行模拟

时间:2019-04-24 22:20:45

标签: r simulation

我正在尝试在模拟中使用分位数来获得90%的间隔。我有一个数据集,其中每一行包含平均值,标准差和要运行的模拟次数。

由于某种原因,当我尝试运行代码时,它只会为整个数据集创建分位数,而不是将每一行中包含的信息用作模拟参数。有什么方法可以使每一行都可以使用它吗?

以下是我正在使用的示例:

avg <- c(24, 20, 29, 17, 22, 21)
sd <- c(5, 4, 5, 3, 3, 3.6)
sims <- 1000
df <- data.frame(avg, sd, sims)

df$Low90 <- round(quantile(rnorm(n = sims, mean = df$avg, sd = df$sd), prob = 0.05), 2)
df$High90 <- round(quantile(rnorm(n = sims, mean = df$avg, sd = df$sd), prob = 0.95), 2)

df
  avg  sd sims Low90 High90
1  24 5.0 1000 14.13  32.32
2  20 4.0 1000 14.13  32.32
3  29 5.0 1000 14.13  32.32
4  17 3.0 1000 14.13  32.32
5  22 3.0 1000 14.13  32.32
6  21 3.6 1000 14.13  32.32

2 个答案:

答案 0 :(得分:2)

使用apply

df$Low90 <- apply(df, 1, function(x) round(quantile(rnorm(n = x[3], mean = x[1], sd = x[2]), prob = 0.05), 2))
df$High90 <- apply(df, 1, function(x) round(quantile(rnorm(n = x[3], mean = x[1], sd = x[2]), prob = 0.95), 2))
df

 avg  sd sims Low90  High90
1  24 5.0 1000 16.08 32.08
2  20 4.0 1000 13.65 26.78
3  29 5.0 1000 20.55 36.96
4  17 3.0 1000 11.94 22.26
5  22 3.0 1000 17.13 26.95
6  21 3.6 1000 14.79 26.84

我们正在做的是使用apply函数,其边距为1,这意味着逐行进行。然后,在每一行中,我们获得meanssdsimulation号,并通过您的模拟函数运行它。

dplyr解决方案将使用rowwise函数,

library(dplyr)
df %>% rowwise %>% 
  mutate(Low90 = round(quantile(rnorm(n = sims, mean = avg, sd = sd), prob = 0.05), 2))

答案 1 :(得分:2)

这是一个使用tidyverse的{​​{1}}方法,因此您只需要对行进行一次迭代即可获得任意数量的分位数。您原始方法的问题在于pmap不能通过其rnorm参数进行向量化;尝试仅运行n,请注意您只能获得一组1000个值。

在这里,我们将使用rnorm(n = sims, mean = df$avg, sd = df$sd)遍历各行,并应用一个自定义函数,该函数需要使用pmap参数中的位数。我们需要使用probsenframe来使这些分位数产生小滴,而不是数字矢量,以便spread将所有内容保持在同一行。好处是,现在,如果您想说每个百分位,您只需更改unnest向量并获得100个新列即可。

probs

reprex package(v0.2.1)于2019-04-24创建