Моделирование по строке в R - PullRequest
1 голос
/ 25 апреля 2019

Я пытаюсь получить 90% интервал, используя квантили, вместо симуляции.У меня есть набор данных, где каждая строка содержит среднее значение, sd и количество симуляций для запуска.

Когда я пытаюсь запустить код, он по какой-то причине создает только квантили для всего набора данных, ачем использование информации, содержащейся в каждой строке, в качестве параметров моделирования.Есть ли способ заставить это работать для каждой строки?

Вот пример того, с чем я работаю:

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 ]

2 голосов
/ 25 апреля 2019

Вот метод tidyverse, который использует pmap, поэтому вам нужно всего лишь один раз пройти по строкам для произвольного числа квантилей. Проблема в вашем первоначальном подходе заключается в том, что rnorm не векторизован по аргументу n; попробуйте просто запустить rnorm(n = sims, mean = df$avg, sd = df$sd) и обратите внимание, что вы получаете только один набор из 1000 значений.

Здесь мы будем использовать pmap для итераций по строкам, применяя пользовательскую функцию, которая принимает столько квантилей, сколько у вас есть в аргументе probs. Нам нужно использовать enframe и spread, чтобы сделать эти квантили тибблами вместо числового вектора, чтобы 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

Создано в 2019-04-24 пакетом Представление (v0.2.1)

2 голосов
/ 25 апреля 2019

Использование 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, что означает переход на ряд.Затем в каждой строке мы получаем числа means, sd и simulation и запускаем их через функцию моделирования.

dplyr решение будет использовать функцию rowwise,

library(dplyr)
df %>% rowwise %>% 
  mutate(Low90 = round(quantile(rnorm(n = sims, mean = avg, sd = sd), prob = 0.05), 2))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...