#r #purrr
#r #purrr
Вопрос:
Я пытаюсь научиться purrr моделировать данные с использованием rnorm с различными средствами, sd и n на каждой итерации. Этот код генерирует мой фрейм данных:
parameter = crossing(n = c(60,80,100),
agegroup = c("a", "b","c"),
effectsize = c(0.2, 0.5, 0.8),
sd =2
) %>%
# create a simulation id number
group_by(agegroup) %>%
mutate(sim= row_number())%>%
ungroup() %>%
mutate(# change effect size so that one group has effect, others d=0
effectsize= if_else(agegroup == "a", effectsize, 0),
# calculate the mean for the distribution from effect size
mean =effectsize*sd)
Теперь я хочу повторить различные симуляции и для каждой строки сгенерировать данные в соответствии со средним значением, sd и r, используя rnorm
# create a nested dataframe to iterate over each simulation and agegroup
nested_df = parameter %>%
group_by(sim, agegroup, effectsize)%>%
nest() %>% arrange(sim)
Вот как тогда выглядит мой фрейм данных:
Теперь я хочу создать нормально распределенные данные со средним значением, sd и n, указанными в столбце «данные»
nested_df = nested_df %>%
mutate(data_points = pmap(data,rnorm))
Однако приведенный выше код выдает ошибку, для которой я не смог найти решение:
Error in mutate_impl(.data, dots) :
Evaluation error: unused arguments
Я прочитал главу об итерации в R for Data Science и погуглил кучу, но я не могу понять, как объединить pmap и nest. Причина, по которой я хотел бы использовать эти функции, заключается в том, что это упростило бы хранение параметров, смоделированных данных и выходных данных в одном фрейме данных.
Ответ №1:
Вам не обязательно вкладывать параметры. Например:
parameter %>%
# Use `pmap` because we explicitly specify three arguments
mutate(data_points = pmap(list(n, mean, sd), rnorm))
# A tibble: 27 x 7
# n agegroup effectsize sd sim mean data_points
# <dbl> <chr> <dbl> <dbl> <int> <dbl> <list>
# 1 60 a 0.2 2 1 0.4 <dbl [60]>
# 2 60 a 0.5 2 2 1 <dbl [60]>
# 3 60 a 0.8 2 3 1.6 <dbl [60]>
С вложенным фреймом данных вы можете использовать map
вместо pmap
:
nested_df %>%
# Use `map` because there is really one argument, `data`,
# but then refer to three different columns of `data`.
mutate(data_points = map(data, ~ rnorm(.$n, .$mean, .$sd)))
Ответ №2:
во-первых, его можно использовать pmap
следующим образом:
x <- tibble(n = 100, mean = 5, sd = 0.1)
pmap(x, rnorm)
что очень похоже на использование do.call
:
do.call(rnorm, x)
Однако, если вы хотите использовать pmap
inside mutate
, вы приводите входные данные для функции .f
в правильную форму.
Написание
nested_df %>%
mutate(y = pmap(x, f))
означает, что f
ожидается ввод x
.
В вашем случае rnorm ожидает три входных данных, но получает только один.
Итак, если вы настаиваете на вложенности входных данных, вы можете сделать это:
nested_df %>%
mutate(data_points = pmap(list(data), function(z) pmap(z, rnorm))[[1]])
или
nested_df %>%
mutate(data_points = pmap(list(data), function(z) do.call(rnorm, z))).
Однако я бы рекомендовал сделать это немного по-другому:
parameter %>%
mutate(data_points = pmap(list(n, mean, sd), rnorm))
Надеюсь, это немного поможет.