R中按行模拟

Simulations by row in R

我正在尝试通过模拟使用分位数获得 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

使用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))

这是一个使用 pmaptidyverse 方法,因此对于任意数量的分位数,您只需要遍历行一次。您原始方法中的问题是 rnorm 未对其 n 参数进行矢量化;尝试 运行 rnorm(n = sims, mean = df$avg, sd = df$sd) 并注意你只得到一组 1000 个值。

在这里,我们将使用 pmap 遍历行,应用一个自定义函数,该函数采用与 probs 参数中一样多的分位数。我们需要使用 enframespread 来制作这些分位数而不是数字向量,以便 unnest 将所有内容保持在同一行。优点是现在如果你想要,比如说,每个百分位数,你可以只改变 probs 向量并获得 100 个新列。

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)

library(tidyverse)
probs <- c(0.05, 0.5, 0.95)
quantile_tbl <- function(sims, avg, sd, probs) {
  rnorm(sims, avg, sd) %>%
    quantile(probs) %>%
    round(2) %>%
    enframe() %>%
    spread(name, value)
}
df %>%
  mutate(quantiles = pmap(select(., sims, avg, sd), ~quantile_tbl(..1, ..2, ..3, probs))) %>%
  unnest()
#>   avg  sd sims    5%   50%   95%
#> 1  24 5.0 1000 15.96 24.04 32.42
#> 2  20 4.0 1000 13.53 20.17 26.72
#> 3  29 5.0 1000 20.59 29.13 37.27
#> 4  17 3.0 1000 11.83 17.08 21.76
#> 5  22 3.0 1000 16.75 22.05 27.17
#> 6  21 3.6 1000 14.87 20.79 26.94

reprex package (v0.2.1)

于 2019-04-24 创建